认识
一、认识
计算属性将会混入到 Vue
实例中。所有的 getter
和 setter
的 this
上下文自动地绑定为 Vue
实例。计算属性的结果会被缓存, 只有计算属性依赖的响应式属性发生变化才会重新计算。如果重新计算的结果与旧值不同, 才会渲染。
二、语法
var vm = new Vue({
data: { a: 1 },
computed: {
// 仅读取
aDouble: function () {
return this.a * 2
},
// 读取和设置
aPlus: {
get: function () {
return this.a + 1
},
set: function (v) {
this.a = v - 1
}
}
}
})
vm.aPlus // => 2
vm.aPlus = 3
vm.a // => 2
vm.aDouble // => 4
三、对比
3.1 computed vs watch
watch
为每一项实例化一个 Watcher
实例, 创建如下 const watcher = new Watcher(vm, expOrFn, cb, { user:true, deep: options.deep })
, 用于监听已有响应式依赖的变化, 如有变化, 触发回调。
computed
为每一项实例化一个 Watcher
实例, 创建如下 watchers[key] = new Watcher( vm, getter || noop, noop, { lazy: true } )
, 并将 computed
的属性 key
代理到 Vue
实例上。 因此, Computed Watcher
是基于其他响应式数据经过一些处理后生成的一个新的响应式状态, 同 data
一致。传入 lazy
配置项, 表示不会立即执行回调函数并计算结果, 只有访问 computed
属性时, 触发 get
函数执行, 检测 watcher.dirty
标记是否为 true
, 为 true
表示在本次渲染周期内没有被执行过, 随后执行回调函数计算结果, 计算时, 所依赖的响应式数据同样会收集当前 Computed Watcher
。如果 watcher.dirty
为 false
, 直接返回计算结果, 具有缓存的作用。
3.2 computed vs methods
如果在一次渲染中,有多个地方使用了同一个 methods
或 computed
属性,methods
会被执行多次,而 computed
的回调函数则只会被执行一次。
通过阅读源码我们知道,在一次渲染中,多次访问 computedProperty
,只会在第一次执行 computed
属性的回调函数,后续的其它访问,则直接使用第一次的执行结果(watcher.value
),而这一切的实现原理则是通过对 watcher.dirty
属性的控制实现的。而 methods
,每一次的访问则是简单的方法调用(this.xxMethods
)。