#javascript #typescript #vue.js #vue-component #vue-class-components
#javascript #typescript #vue.js #vue-компонент #vue-class-components
Вопрос:
У меня проблема в том, что мой пользовательский интерфейс каким-то образом не обновляется после того, как приложения извлекают некоторые данные из серверной части сервера.
У меня есть следующий код:
<template>
<div v-if="restaurant">
<div class="center logo-container">
<img class="img-fit" v-bind:src="'/api/restaurant/logo/' restaurant.id" alt=""/>
</div>
<h2 class="title center dm-text-header">{{ restaurant.name }}</h2>
<h4 class="subheading center">{{ restaurant.address.street }}, {{ restaurant.address.city }}</h4>
</div>
</template>
<script lang="ts">
import axios from 'axios';
import { Options, Vue } from "vue-class-component";
import { Tag } from "./Tag";
import { Restaurant } from "./Restaurant";
@Options({
props: {
}
})
export default class Menu extends Vue {
// hardcoded for testing
restaurantId = "8ykw9ljq";
tagUrl = "/api/menu/" this.restaurantId "/tags";
restaurantUrl = "/api/restaurant/" this.restaurantId;
restaurant!: Restaurant;
tags: Tag[] = [];
mounted() {
// get tags
this.getTags();
// get restaurant
this.getRestaurant();
}
getRestaurant(): void {
axios.get<Restaurant>(this.restaurantUrl)
.then(res => {
this.restaurant = res.data;
});
}
getTags(): void {
axios.get(this.tagUrl)
.then(res => {
this.tags = res.data;
});
}
}
</script>
Я проверил, что серверная часть действительно обслуживает правильный ресторан, и зарегистрировал результаты после завершения вызова axios. Проблема в том, что DOM не обновляется. Если я добавлю следующее к DOM, DOM будет обновлен:
<template>
...
<div>
{{tags}}
</div>
<template>
Мне кажется, что vue каким-то образом обновил DOM только в том случае, если он распознает изменения в уже инициализированном пустом массиве, но не в текущем неинициализированном объекте restaurant.
Далее я получаю предупреждение: [Vue warn]: Property "restaurant" was accessed during render but is not defined on instance.
о v-if
том, что я нахожу странным, потому что это точная причина, по которой оно существует. Как мне нужно инициализировать ресторан, чтобы обновление через axios правильно распозналось vue?
Ответ №1:
Попробуйте объединить Typescript с null
:
restaurant: Restaurant | null = null;
Из документации по компоненту класса Vue:
Обратите внимание, что если начальное значение не определено, свойство класса не будет реагировать, что означает, что изменения свойств не будут обнаружены
и
Чтобы избежать этого, вы можете использовать значение null или вместо этого использовать перехват данных:
import Vue from 'vue'
import Component from 'vue-class-component'
@Component
export default class HelloWorld extends Vue {
// `message` will be reactive with `null` value
message = null
// See Hooks section for details about `data` hook inside class.
data() {
return {
// `hello` will be reactive as it is declared via `data` hook.
hello: undefined
}
}
}