Why is this Vue computed property not reactive?

☆樱花仙子☆ 提交于 2019-12-24 19:33:56

问题


I'd like my view, using an id passed as a prop, to lookup an object's property in the store. The object in the store appears asynchronously, so the object might not be present right away. I'd like the view to react to the object's eventual appearance.

<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>

Using vuex debug tools, I can watch the store widgets object start out empty and then get set with widgets: { 'widgets/someId': { ... } }, but my vue doesn't seem to pick up the change. The title remains == 'nothing...'.

I tried making these methods, but I get the same behavior. I also tried replacing the whole widgets object on the store, instead of one prop at a time (I think that's a requirement), but still no luck.

I think my question is very similar to this one, but the answer there is too terse. It just says "use a data item", but I don't really know what that is or how to use it (or why that will make the vue reactive).


回答1:


Mutations Follow Vue's Reactivity Rules

Since you're watching it go from empty to having some members, you are falling afoul of Vue's change detection caveats.

Vue cannot detect property addition or deletion.

You need to use Vue.set when adding or deleting members, even in Vuex.




回答2:


Your widget is most likely not reactive, because widget itself does not change, and neither does widget.data because it is a function you define. Vue does not "see" the changes in data when data is called, because it is a function.

You have several ways of making your widget reactive. One is by precomputing your data and returning an object without functions. This could mean a performance drop when you have a lot of widgets, even though you do not need the data in most of them.

Another one is by potentially using the relatively new getter function/method. You would get your data with widget.data and have a widget like

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

Remember that this is (I believe) an Ecmascript 6 feature, so you will likely need to run this through babel to be compatible with all relevant browsers.



来源:https://stackoverflow.com/questions/54715544/why-is-this-vue-computed-property-not-reactive

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!