computed 实现的本质- lazy watcher
在 Vue 实例初始化过程中,在生命周期 beforeCreate
、 created
之间,调用 initState
方法进行各属性的初始化(props、data、methods、computed、watch)
// /src/core/instance/init.js
export function initMixin (Vue: Class<Component>) {
Vue.prototype._init = function (options?: Object) {
...
initLifecycle(vm)
initEvents(vm)
initRender(vm)
callHook(vm, 'beforeCreate')
initInjections(vm) // resolve injections before data/props
initState(vm)
initProvide(vm) // resolve provide after data/props
callHook(vm, 'created')
...
}
}
// /src/core/instance/state.js
export function initState (vm: Component) {
vm._watchers = []
const opts = vm.$options
if (opts.props) initProps(vm, opts.props)
if (opts.methods) initMethods(vm, opts.methods)
if (opts.data) {
initData(vm)
} else {
observe(vm._data = {
}, true /* asRootData */)
}
if (opts.computed) initComputed(vm, opts.computed)
if (opts.watch && opts.watch !== nativeWatch) {
initWatch(vm, opts.watch)
}
}
而本文就 Vue 如何实现 Computed 计算属性做深入的分析,即查看 initComputed
中的具体是如何实现的。
// /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) {
// userDef 存在两种情况
// 一种是常见的定义为方法即该方法默认为get
// 另外就是自定义get和set,故类型为对象