为什么该Vue计算属性不具有反应性?

时间:2019-02-15 18:58:08

标签: javascript vue.js vuex

我希望通过使用ID作为道具传递的视图在商店中查找对象的属性。存储中的对象异步出现,因此该对象可能不会立即出现。我希望视图对对象的最终外观做出反应。

<template>
  <div>
    <h1>{{ title }}</h1>
  </div>
</template>

<script>
export default {
  props: ['id'],
  computed: {
    widget () {
      let path = `widget/${this.id}`
      return this.$store.state.widgets[path]
    },
    title () {
      let widget = this.widget
      return (widget) ? widget.data().fullName : 'nothing to see here'
    }
  }
}
</script>

使用vuex调试工具,我可以观察到商店小部件对象开始为空,然后用widgets: { 'widgets/someId': { ... } }进行设置,但是我的vue似乎没有把握这一变化。标题仍为=='没什么...'。

我尝试制作这些方法,但行为却相同。我还尝试替换了商店中的整个widgets对象,而不是一次替换一个道具(我认为这是必要条件),但还是没有运气。

我认为我的问题与this one非常相似,但是答案太简洁了。它只是说“使用数据项”,但我真的不知道这是什么或如何使用(或为什么会使vue具有反应性)。

2 个答案:

答案 0 :(得分:1)

Mutations Follow Vue's Reactivity Rules

由于您正在观察它从空到有一些成员,因此您正在违反Vue的change detection caveats

  

Vue无法检测到属性的添加或删除。

即使在Vuex中,添加或删除成员时也需要使用Vue.set

答案 1 :(得分:0)

您的窗口小部件很可能没有反应,因为widget本身不会更改,widget.data也不会更改,因为它是您定义的函数。调用data时,Vue无法“看到”数据的更改,因为它是一个函数。

您可以通过多种方式使小部件具有反应性。一种是通过预先计算数据并返回没有函数的对象。即使您不需要大多数小部件中的数据,这也可能意味着当您有很多小部件时性能下降。

另一种方法是潜在地使用相对较新的getter函数/方法。您将使用widget.data获取数据,并拥有一个类似

的小部件
{
  id: 1,
  get data() {
    // Whatever was in your function before
  }
}

请记住,这是(我相信)Ecmascript 6功能,因此您可能需要通过babel运行此功能,以与所有相关浏览器兼容。