#javascript #vue.js
Вопрос:
Я учусь vue.js и пытается вызвать файл json и проанализировать данные. Все работает, но когда я обновляю страницу, я вижу пустую страницу до загрузки моих данных и в журнале консоли, который я получаю TypeError: e.myData is null
. Через несколько секунд данные отображаются на странице.
main.js
:
new Vue({
el: `#app`,
render: h => h(App,{
props:{
todoID: this.dataset.id
}
})
})
и мой App.vue
:
<template>
<div>
<div>{{myData.getName()}}</div>
</div>
</template>
<script>
import Info from '@/getInfo'
export default {
name: 'App',
props: {
todoID: String,
},
data() {
return {
data: null,
myData: null
}
},
created() {
fetch(`http://localhost/json-end-point/`)
.then(async response => {
const data = await response.json();
if (!response.ok) {
const error = (data amp;amp; data.message) || response.statusText;
return Promise.reject(error);
}
// set the date here, am I doing this right?
this.myData = new Info(data);
this.data = data;
})
.catch(error => {
this.errorMessage = error;
console.error("There was an error!", error);
});
}
}
</script>
getInfo.js
export default class Info {
constructor(Data) {
if (Data) {
const data = JSON.parse(Data);
console.log(data.name); // returns name
// console.log(data); // returns the json data
this.name = data.name;
}
}
getName() {
return this.name;
}
}
Я думаю, что делаю здесь что-то не так this.myData = new Info(data);
, но я не уверен, что могу сделать.
Обновить
Я смог удалить журнал консоли, добавив v-if="myData !== null"
. Все еще не уверен, что назначение подобных данных this.myData = new Info(data);
-хороший подход. Как я могу улучшить этот код?
Комментарии:
1. вы можете добавить v-if в шаблон, чтобы показать его, если переменная не равна нулю. прямо сейчас страница отображается до завершения вызова
2. спасибо, что
v-if="myData !== null"
удалил журнал консоли. Является лиthis.myData = new Info(data);
это хорошим подходом? или мне следует попробовать другой способ? Я не хочу учиться не так, как надо.3. используя новые средства, вы не можете возвращать обещание и ждать, лучшим подходом было бы обернуть выборку в асинхронную функцию
4. @KareemKamal у вас есть пример?
5. да, добавлен ответ с примером
Ответ №1:
Вот пример того, как позволить шаблону отображать разные состояния, чтобы он не пытался отобразить данные до их поступления, а вместо этого показывал индикатор загрузки.
<template>
<div v-if="myData">
<div>{{ myData.getName() }}</div>
</div>
<div v-else-if="isLoading">
Loading data...
</div>
<div v-else-if="errorMessage">
{{ error.message }}
</div>
</template>
<script>
import Info from '@/getInfo'
export default {
name: 'App',
props: {
todoID: String,
},
data() {
return {
data: null,
myData: null,
error: null
}
},
async created() {
await this.getData()
},
methods: {
async getData() {
try {
const response = await fetch(`http://localhost/json-end-point/`)
if (!response.ok) {
throw new Error(data?.message || response.statusText)
}
this.data = await response.json();
this.myData = new Info(this.data);
} catch (error) {
this.error = error;
console.error("There was an error!", error);
}
}
}
}
</script>
Комментарии:
1. это возвращает ошибку
Module build failed, reserved word 'await'
для этой строкиthis.myData = await getData()
2. забыл
this.
о том , что было раньшеgetData
, попробуй с этим3. спасибо, все та же ошибка
4. добавлена асинхронность к созданному крючку, извините, я слишком привык к тому, что линтер делает это за меня.
5. нашел его! функция возвращает значение undefined, и мы присваиваем значение undefined myData в created (), удаление назначения исправляет это
Ответ №2:
Вы можете поместить myData.getName()
вызов в вычисляемое поле, которое либо возвращает имя, myData != null
либо пустую строку (или любое другое значение, которое вы хотите, когда данные недоступны).
Что-то вроде этого
computed: {
getName() {
return this.myData ? this.myData.getName() : '';
}
}