在實例化Vue對象得時候,咱們經過computed來定義計算屬性:express
var vm = new Vue({ el: '#example', data: { message: 'Hello' }, computed: { // 計算屬性的 getter reversedMessage: function () { return this.message.split('').reverse().join('') } } })
在實例化時,初始化計算屬性initComputed(源碼路徑/src/core/instance/state.js)oop
for (const key in computed) { const userDef = computed[key] const getter = typeof userDef === 'function' ? userDef : userDef.get .... //定義Watcher vm._computedWatchers[key] = new Watcher({ vm, getter || noop, noop, { lazy: true } //調用時才計算屬性的值 }) // defineComputed(vm, key, userDef) }
在defineComputed從新定義屬性this
Object.defineProperty(vm, key, { get : function(){ const watcher = this._computedWatchers && this._computedWatchers[key] if (watcher) { if (watcher.dirty) { //this.dirty = this.lazy watcher.evaluate() //調用get設置watcher.value的值 } if (Dep.target) { watcher.depend() } return watcher.value } } })
總結初始化流程以下:lua
evaluate () { this.value = this.get() this.dirty = false } get () { pushTarget(this) let value const vm = this.vm try { value = this.getter.call(vm, vm) //調用getter獲取value值 } catch (e) { if (this.user) { handleError(e, vm, `getter for watcher "${this.expression}"`) } else { throw e } } finally { if (this.deep) { traverse(value) } popTarget() this.cleanupDeps() } return value }