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
  }
相关文章
相关标签/搜索