【发布时间】:2019-11-05 18:23:27
【问题描述】:
在这个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 getter 中),并且大多数情况下,即使某些数据发生变化,减少的数据也不会改变。
已编辑以添加更多细节:vuex store 中的数据已标准化。我们还使用了vue-grid-layout,它期望其layoutproperty 采用certain 非规范化格式。所以我们有一个 gridLayout getter 来执行 vuex -> vue-grid-layout 转换。观察这个 gridLayout getter 即使生成的 gridLayout 实际上没有改变,但其他细节发生了变化,例如 vuex 存储中的名称和其他与 vue-grid-layout 无关的对象键。
现在在上面的示例中,当this.counter 更改时,test 上的监视也会触发,即使 newVal 和 oldVal 是“相同的”。请注意,它们不是== 或===,而是与JSON.stringify(newVal) == JSON.stringify(oldVal) 中的“相同”。
有没有办法让我的watch 仅在发生实际更改时触发?实际上比较 JSON.stringify() 对我来说似乎效率低下,但我担心随着项目的增长会出现性能问题,因为我的手表可能会进行昂贵的操作,并且我想确保我不会遗漏任何东西。
【问题讨论】:
-
您能否更详细地说明您将使用观察器的目的?根据您尝试做的事情,它可能会在您的架构决策中得到解决。我用 vue 创建了一个大型企业 SPA,由于性能原因,我最终删除了大多数 getter,最终将它们移动到一个混合库中,以便在上下文中调用,而不是在底层状态对象更新时调用。
-
@TimWickstrom:我已更新问题以根据要求添加更多详细信息。
标签: vue.js