【发布时间】:2021-09-14 07:26:54
【问题描述】:
我对计算属性的理解是,如果模板中没有使用计算属性,则不应该计算它。然而,当有一个计算属性的观察者时,这个计算属性会被计算。
我知道这不是所需的应用程序架构,但我的问题是,它以这种方式工作的事实是否是所需的 Vue 行为,或者是当前实现方式的一些副作用,并且在未来的版本中可能会发生变化?
或者换句话说: 如果计算的属性没有在模板中使用并且在代码库中没有其他显式的 getter(除了观察者),是否应该评估它?
例子:
<template>
<div>
<button @click="counter++">+1</button>
{{ counter }}
</div>
</template>
<script>
export default {
name: "Main",
data() {
return {
counter: 0,
};
},
computed: {
notUsedInTemplate() {
console.log("notUsedInTemplate computed called");
return this.counter + 1;
},
},
watch: {
notUsedInTemplate() {
console.log("notUsedInTemplate watch called");
},
},
};
</script>
沙盒链接:https://codesandbox.io/s/computed-sandbox-ru3n3?file=/src/components/Main.vue:0-818
【问题讨论】:
-
形成您在计算属性中编写的逻辑,您可以将其放弃并从
watch对象中将计数器加一 -
组件中的实际逻辑要复杂得多。问题中的一个只是为了更好地描述问题。我知道它应该在
watch中完成,但现实生活中的这种重构不是我现在负担得起的。我想从行业中获得更多的洞察力,以了解这是 Vue 的期望行为还是未来版本中可能会消失的东西。基于这些知识,我可以优先考虑重构。 -
vue 推荐使用计算比较来观看。可能的原因可能是性能,声明式与命令式,计算式易于处理和设置比较以观察。 vuejs.org/v2/guide/computed.html
-
您能解释一下为什么这对您来说很重要吗?您在计算属性中所做的一切都必须没有副作用。因此,您不得设置/修改其中的任何属性(或调用可能导致此结果的函数)或使用任何非反应性的非本地值(
const可能没问题)。严格来说,您的console.log("notUsedInTemplate computed called");也会产生副作用。因此,从您的值状态和应用程序的角度来看,watch是否触发对计算属性的调用不会有任何区别。 -
知道这一点对我来说很重要,因为我更喜欢了解我使用的框架,这种行为让我很惊讶。 @michal-levý 在他的 comment 中提出了一个很好的观点,在浏览了 Vue 的代码库之后,我明白了它为什么会这样工作。
标签: javascript vuejs2 vue-component