VUE2.6.10——computed計算屬性

computed初始化

在實例化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

  • 爲每一個計算屬性初始化一個Watcher對象,保存在實例得_computedWatchers變量中
  • 從新定義計算屬性得get屬性,經過watch獲取返回屬性的值。

Watcher

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
  }
相關文章
相關標籤/搜索