在此codepen中,有一个计数器,该计数器可以通过“ incr”链接递增。
我现在有一个计算属性和一个手表:
computed: {
test() {
let unused = this.counter;
return [42];
}
},
watch: {
test(val, old) {
// Should I avoid firing when nothing actually changed
// by implementiong my own poor-man's change detection?
//
// if (JSON.stringify(newVal) == JSON.stringify(oldVal))
// return;
console.log(
'test changed',
val,
old
);
}
}
也许是一个人为的例子,但实际上,这是一种计算(在vuex吸气剂中)的真实数据被精简,并且即使某些数据发生更改,精简后的数据也不会更改。
已编辑以添加更多详细信息:vuex store
中的数据已标准化。我们还使用vue-grid-layout,期望其layout
属性为certain非规范格式。因此,我们有一个gridLayout
吸气剂,可以进行vuex-> vue-grid-layout转换。即使在生成的gridLayout实际没有更改的情况下,观看此gridLayout getter也会触发,但是其他详细信息也会更改,例如vuex存储中的名称和其他与vue-grid-layout相关的对象键。
现在在上面的示例中,当this.counter
发生变化时,即使test
和newVal
“相同”,oldVal
上的手表也照常亮起。它们不是==
或===
介意的,而是与JSON.stringify(newVal) == JSON.stringify(oldVal)
中的“相同”。
有什么方法可以让我的watch
仅在进行实际更改时才会被触发?实际上,比较JSON.stringify()
对我来说似乎效率低下,但是随着项目的发展,我的性能问题会越来越严重,因为我的手表可以进行昂贵的操作,并且我想确保自己不会错过任何东西。
答案 0 :(得分:0)
根据Vue.js文档,无论何时更改反应性依赖项,都将重新评估计算的属性。
在您的情况下,反应相关性为this.counter
通过调用与计算属性相反的方法,可以获得相同的结果。
只需更改您的组件架构:
data () {
return: {
counter: 0,
obj: {},
output: null
}
},
watch: {
counter(val, old) {
// Alternatively you could remove your method and do something here if it is small
this.test(val);
},
// Deep watcher
obj: {
handler: function (val, oldVal) {
console.log(val);
console.log(oldVal);
this.test(val);
},
deep: true
},
}
},
methods: {
test() {
let unused = this.counter;
if (something changed)
this.output = [42];
}
}
}
现在模板(或其他计算的属性)中的output
是反应性的
了解更多:https://vuejs.org/v2/guide/computed.html#Computed-Caching-vs-Methods