有知乎网友问:
vue的computed如果没有出现在模板里面,当它依赖的响应式属性发生变化,getter会触发吗?
先说答案,不会触发!
原因说穿了其实也很简单,因为你没有在模板中使用该计算属性,所以该计算属性所依赖的的响应式属性不认为你这个计算属性有依赖它,所以它改变了就不会去通知计算属性getter做任何事情。
再往深点说,原因就是因为计算属性watcher在这种情况下没有被作为依赖收集到它依赖的响应属性上,所以就算该响应属性变出了大呲花也不会通知计算属性watcher去触发getter来求值的。
下面会详细点阐述下为什么会这样子?
计算属性的实现是这样子的,举个例子,当我们在我们的组件中写了:
{
data: {counter: 1}
computed: {
twiceCounter: function() {
return this.counter * 2;
}
}
那么vue在初始化组件的时候,会经历以下这些流程
- 为该计算属性创建一个计算属性watcher,但,问知道计算属性是惰性求值的,所以这时并不会触发任何求值和收集依赖的动作
- 跟着,vue会在组件实例对象中增加一项叫做‘twiceCounter’的key,然后通过defineProperty重写其getter为computedGetter的方法。这就是为什么我们可以直接通过this.twiceCounter访问我们的计算属性的原因
- 然后,在这种情况下就真的没有然后了!
如果你页面模板中有引用计算属性如twiceCounter的话,那么我们就有然后:
- 组件初始化过程中会触发虚拟dom的重新生成,即render方法也就是传奇的h函数调用,期间会分析读取页面引用的data和computed的数据,当然也包括我们这里的计算属性了
- 一旦访问计算属性,就会触发其getter,也就是我们上面的computedGetter,
这时computedGetter就开始做事情了。computedGetter会调用计算属性watcher来开始调用我们写的计算属性getter求值并进行依赖收集,让计算属性watcher成为依赖响应式属性counter的依赖
所以,这里如果依赖的响应属性发生变化,必然会触发计算属性watcher来调用我们写的计算属性getter求值。
但是,可惜的是,你页面模板没有引用我这个计算属性,导致我这个计算属性的watcher根本没有加入到counter这个响应属性的依赖中,所以,就算我counter改变后想通知你也无门了!
以上回答如果看起来有点吃力的话,建议先看下我其他一些说vue原理的文章:
我是@天地会珠海分舵,能力一般,水平有限,觉得我说的还有那么点道理的不妨点个赞关注下!