我有一个对象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()
也未启动。为什么?
答案 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)