У меня странная проблема в приложении Vue. Компонент выглядит следующим образом:
...
<template v-for="foo in foos">
<Elm v-if="foo.visible" :key="foo.label" :bar="foo" />
</template>
...
"Elm" - это значение в объекте, полученном из файла JSON. Компонент реагирует, если я получаю файл JSON локально:
<script>
import datas from "datafile.json";
...
methods: {
fillFoos() {
datas.forEach(data => {
this.foos.push(data)
})
}
},
mounted: {
this.fillFoos()
}
...
</script>
Но когда я извлекаю файл удаленно с помощью fetch, компонент перестает быть реактивным и больше не исчезает при изменении значения foo.visible:
<script>
methods: {
getDataFromApi() {
return new Promise((resolve, reject) => {
fetch(this.apiUrl)
.then(response => {
return response.json();
})
.then(jsonResponse => {
resolve(jsonResponse);
})
.catch(e => {
...
})
})
},
fillFoos() {
this.getDataFromApi()
.then(response => {
response.forEach(data => {
this.foos.push(data);
});
});
}
},
mounted: {
this.fillFoos()
}
...
</script>
В обоих случаях массив "foos" правильно заполнен, единственное отличие состоит в том, что директива v-if, по-видимому, нарушена во втором случае. Точнее, отображение выполняется правильно при инициализации (foo.visible истинно для всех элементов, и все они отображаются), но в случае более позднего изменения значения foo.visible они не исчезают.
Я не могу найти, что неправильно...
Я считаю, что проблема, с которой вы сталкиваетесь, заключается в том, что метод getDataFromApi
возвращает обещание, но когда вы его потребляете в fillFoos
обещание не ожидается, вместо этого вы вызываете forEach
на нем.
Вам нужно использовать getDataFromApi().then(x => {})
синтаксис для решения обещания или, альтернативно, вы можете использовать async await
.
Вы можете попробовать что-то вроде этого
methods: {
async getDataFromApi() {
const response= await fetch(this.apiUrl);
return response.json();
},
async fillFoos() {
try {
await foos = this.getDataFromApi();
this.foos = foos;
} catch(error) {
//handle error.
}
}
}
response.json()
- это Обещание, поскольку body
может передаваться потоком.
Вчера кто-то опубликовал ответ, очень близкий к решению, но удалил его, я не знаю, почему. Проблема заключалась в том, что я сохранил ответ на выборку в переменной в разделе данных, прежде чем использовать ее для заполнения таблицы "foos"
data: function() {
return {
dataFromApi: null
}
}
Удалив эту переменную и, таким образом, создав ее на лету после извлечения, все работает нормально.... Я не указывал, что я сохранил ответ в этой переменной, потому что я не думал, что это может быть связано... Мораль: всегда указывайте все!
v-for
является ли этот шаблонный тег для файла.vue
? Кроме того, можете ли вы поделиться полезной нагрузкой, которую вы получаете, когда выполняете обещание?