为什么添加密钥不会触发监视变量?

时间:2018-04-18 14:48:35

标签: vue.js vue-component

我有一个对象allevents使用键和值异步更新。每当allevents被修改时,我想触发重新计算功能。

为此,我使用以下Vue结构(在组件中,删除了所有不相关的元素):

export default {
        data: function () {
            return {
                //
                allevents: {},
                events: []
            }
        },
        methods: {
            //
            mqttMessage(topic, message) {
                const cal = topic.split('/').pop()
                this.allevents[cal] = JSON.parse(message).filter(x => true)
                // following the update above, I was expecting that since 
                // allevents is watched below, the function would trigger
                // as a workaround, I added this line below which fixes the issue
                // but I still would like to understand the lack of trigger
                this.computeEvents()
            },
            // the function ssupposed to be triggred after a chnage, below
            computeEvents() {
                this.events = []
                Object.values(this.allevents).forEach(cal => cal.forEach(e => this.events.push(e)))
            }
        },
        watch: {
            // whenever allevents change, run computeEvents() <-- this does not happen
            allevents() { 
                console.log("events compute triggered")
                this.computeEvents() 
            }
        },
        mounted() {
            //
        }
}

即使allevents被修改并被观看,computeEvents()也未启动。为什么?

1 个答案:

答案 0 :(得分:2)

您似乎是Reactivity/Change Detection Caveat的受害者。

而不是:

this.allevents[cal] = JSON.parse(message).filter(x => true)

尝试:

Vue.set(this.allevents, cal, JSON.parse(message).filter(x => true))

或者:

this.$set(this.allevents, cal, JSON.parse(message).filter(x => true))

the docs的相关摘录:

  

更改检测警告

     

由于现代JavaScript的局限性(以及放弃   Object.observe),Vue 无法检测属性添加或   缺失即可。由于Vue执行getter / setter转换过程   在实例初始化期间,属性必须存在于   data对象,以便Vue将其转换并使其具有反应性。对于   例如:

     
var vm = new Vue({
  data: {
    a: 1
  }
})
// `vm.a` is now reactive
vm.b = 2
// `vm.b` is NOT reactive
     

Vue不允许动态添加新的根级反应   已创建实例的属性。但是,有可能   使用Vue.set(object, key, value)方法将反应属性添加到嵌套对象:

     
Vue.set(vm.someObject, 'b', 2)
     

您还可以使用vm.$set实例方法,该方法是别名   全球Vue.set

     
this.$set(this.someObject, 'b', 2)