Я хочу загрузить некоторое содержимое компонента vue на основе заданного аргумента. Вот код для иллюстрации:
РодительскийКомпонент.vue
<Suspense>
<div class = "row g-0">
<div class = "col-md-3">
<ChildComponent json-url = "some/url/to/json/data" />
</div>
<div class = "col-md-3">
<ChildComponent json-url = "some/url/to/json/data" />
</div>
<div class = "col-md-3">
<ChildComponent json-url = "some/url/to/json/data" />
</div>
<div class = "col-md-3">
<ChildComponent json-url = "some/url/to/json/data" />
</div>
</div>
<template #fallback>
<p>Loading...</p>
</template>
ChildComponent.vue
<template>
<!-- some content based on the loaded json data -->
</template>
<script setup>
import { ref, onMounted} from 'vue';
defineProps({jsonUrl: {
type: String,
default: ""
}})
const images = ref(null);
const thumbnail = ref(null);
const title = ref("");
const description = ref("");
onMounted(async () => {
try {
const response = await fetch(new URL(jsonUrl, import.meta.url).href);
if (!response.ok) {
throw new Error('Network response was not ok');
}
var jsonData = await response.json();
images = jsonData["images"];
thumbnail = jsonData["thumbnail"];
title = jsonData["title"];
description = jsonData["description"];
console.info(thumbnail);
} catch (error) {
console.error('Error fetching the JSON file:', error);
}
});
</script>
Проблема в том, что jsonUrl не доступен во время обратного вызова onMounted(). Именование и все должно работать, поскольку, если я просто поставлю <p>{{json}}</p> в шаблон, URL-адреса будут отображаться правильно.
Я немного поискал, но кажется, что недвижимость должна быть свободна? Например, ответ на этот пост демонстрирует практически тот же подход (с той лишь разницей, что используется машинописный текст). Как я могу правильно загрузить и инициализировать свой контент на основе данных json в моем дочернем компоненте здесь?
@kissu спасибо за ссылку. Это кажется правдоподобным, позвольте мне проверить. Между тем, есть ли еще одна функция обратного вызова, которую я могу/должен использовать для такого рода вариантов использования?
Возможно, можно использовать Suspense для более детального управления потоком ваших звонков: vuejs.org/guide/built-ins/suspense.html#suspense Я не помню все способы решения этой проблемы, но есть несколько.
И да - простой console.info() показывает, что детей вызывают раньше родителей.
Как уже было сказано, используйте для этого приостановку и переместите асинхронный код в тело настройки. thumbnail = - это ошибка, вы теряете реактивность переназначая реф. «Похоже, что jsonUrl недоступен» — как вы проверили? «новый URL(jsonUrl, import.meta.url)» — это выглядит подозрительно, поскольку вы пытаетесь получить что-то из src/, это работает не так



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


При использовании настройки вам необходимо определить переменную props:
const props = defineProps({jsonUrl: {
type: String,
default: ""
}})
Затем используйте props.jsonUrl, чтобы получить доступ к реквизиту. Это должно позволить вам получить доступ к реквизиту внутри onMounted
Извините, но мой код уже содержит defineProps, поэтому проблема в другом (согласно комментариям выше, скорее всего, это связано с жизненным циклом)
Я имел в виду, что вы не устанавливаете реквизиты для переменной в своем коде, вам нужно только добавить часть const props = перед defineProps(...
Ах, ок, в любом случае это не имеет особого значения. Хотя я не могу найти его в документации, я где-то читал, что это не нужно и назначается автоматически. Но все равно спасибо за предложение :)
На самом деле я ошибался. Как уже отмечалось, ваш фактический ответ с использованием props.jsonUrl работает немедленно. Итак, ваш подход работает (в сочетании с тем фактом, указанным в комментариях выше, что я могу просто поместить все в тело асинхронной настройки). Теперь мне просто любопытно, что происходит за кулисами со свойствами, и может ли это привести к каким-либо проблемам в будущем?
Что именно вы имеете в виду под словами «что происходит за кулисами»? Может быть, я мог бы немного объяснить
Ну, defineProps() каким-то образом инициализирует свойства, они доступны где-то позже в жизненном цикле, без предварительного назначения чего-либо props. Мне просто интересно, как именно работает эта инициализация. В любом случае я не думаю, что что-то нарушаю, поскольку я только читаю значение, а не присваиваю ничего.
SFC (однофайловые компоненты) компилируются в рабочий JavaScript. defineProps — это макрос компилятора (поэтому его не нужно импортировать), который сообщает компилятору определить реквизиты. Он будет скомпилирован примерно так (упрощенно): ``` { props: ['jsonUrl'], setup(props) { // Остальная часть кода вашего компонента } } ``` Как видите, остальная часть ваш код будет помещен в метод setup, который сразу же получит доступ к переменной props.
отлично, спасибо за информацию!
Наверное, из-за этого? stackoverflow.com/a/44319825/8816585