Vue 类组件属性未在实例上定义

Ste*_*ann 2 javascript typescript vue.js vue-component vue-class-components

我遇到的问题是,在应用程序从服务器后端获取一些数据后,我的 UI 无法更新。

我有以下代码:

<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>
Run Code Online (Sandbox Code Playgroud)

我验证了后端确实为正确的餐厅提供服务,并在 axios 调用完成后记录结果。问题是 DOM 没有更新。如果我将以下内容添加到 DOM 中,则会更新:

<template>
...
  <div>
    {{tags}}
  </div>
<template>
Run Code Online (Sandbox Code Playgroud)

在我看来,vue 仅在识别到已初始化的空数组的更改而不是当前未初始化的餐厅对象时才更新 DOM。

我进一步收到警告: [Vue warn]: Property "restaurant" was accessed during render but is not defined on instance.关于v-if我觉得奇怪的事情,因为这就是它存在的确切原因。我需要如何初始化餐厅,以便 vue 正确识别通过 axios 进行的更新?

Dan*_*Dan 5

尝试使用Typescript联合null

restaurant: Restaurant | null = null;
Run Code Online (Sandbox Code Playgroud)

来自 Vue 类组件文档

请注意,如果初始值未定义,则类属性将不会响应,这意味着将不会检测到属性的更改

为了避免这种情况,您可以使用 null 值或使用数据挂钩:

restaurant: Restaurant | null = null;
Run Code Online (Sandbox Code Playgroud)