目录
阅读本文前题是,已经对vue数据绑定机制中的的observer和watcher原理有个大致的了解,只要知道一个watcher去get一个data时,就会建立一个互相绑定的关系,data的会把watcher存人dep.subs数组,知道都有谁在watch它,以便发生变化时通知,而watcher也会把data的dep放入自己的deps数据,知道自己依赖哪些数据。
在此基础上,本文进一步讲解一下computed的原理,整体流程图如下,可对照此图理解后面的内容:
1. computed初始化
在初始化组件创建组件实例时,会调用到initComputed函数,这里会初始化组件里定义的computed属性,代码如下:
// vue/src/core/instance/state.js
const computedWatcherOptions = {
lazy: true }
function initComputed (vm: Component, computed: Object) {
// $flow-disable-line
const watchers = vm._computedWatchers = Object.create(null)
// computed properties are just getters during SSR
const isSSR = isServerRendering()
for (const key in computed) {
const userDef = computed[key]
const getter = typeof userDef === 'function' ? userDef : userDef.get
if (process.env.NODE_ENV !== 'production' && getter == null) {
warn(
`Getter is missing for computed property "${
key}".`,
vm
)
}
if (!isSSR) {
// create internal watcher for the computed property.
watchers[key] = new Watcher(
vm,
getter || noop,
noop,
computedWatcherOptions
)
}
// component-defined computed properties are already defined on the
// component prototype. We only need to define computed properties defined
// at instantiation here.
if (!(key in vm)) {
defineComputed(vm, key, userDef)
} else if (process.env.NODE_ENV !== 'production') {
if (key in vm.$data) {
warn(`The computed property "${
key}" is already defined in data.`, vm)
} else if (vm.$options.props && key in vm.$options