分析一下新版的计算属性

来源:5-2 计算属性 VS 侦听属性(2)

哈哈大笑x

2020-03-15

老师您好,麻烦您看一下我分析得对不对


render生成vnode过程中访问到name执行computedGetter,以下代码

function createComputedGetter (key) {
  return function computedGetter() {
    var watcher = this._computedWatchers && this._computedWatchers[key];
    if (watcher) {
      if (watcher.dirty) {
        watcher.evaluate();
      }
      if (Dep.target) {
        watcher.depend();
      }
      return watcher.value
    }
  }
}

首先是这个函数中,执行watcher.evalute(),然后执行getter(客户写入computed里面的name方法)。
访问到this.useless的时候(this.useless的get),进行依赖收集:

把this.useless的dep push到computed的watcher的newDeps中(后面cleanupDeps会赋值给deps),
接着把computed的watcher push到this.useless的dep.subs中(computed的watcher对this.useless的dep进行订阅),也就是下面代码:

addDep (dep: Dep) {
  const id = dep.id
  if (!this.newDepIds.has(id)) {
    this.newDepIds.add(id)
    this.newDeps.push(dep)
    if (!this.depIds.has(id)) {
      dep.addSub(this)
    }
  }
}
addSub (sub: Watcher) {
  this.subs.push(sub)
}

然后watcher.depend(),实际上就是通过computed的deps拿到this.useless的dep.subs再把渲染watcher push 进去(渲染watcher对this.useless的dep进行订阅),同时渲染watcher的deps中也添加了this.useless的dep。


到修改的时候,执行this.useless的set,再调用dep.notify,然后遍历this.useless的dep.subs中的两个watcher(computer的watcher和渲染watcher)进行update

update () {
  if (this.lazy) {
    this.dirty = true
  } else if (this.sync) {
    this.run()
  } else {
    queueWatcher(this)
  }
}

第一次是把this.dirty置为true,因为它是计算属性的watcher。第二次直接执行queueWatcher进行渲染。
这样是不是就是减少了计算,只要修改了this.useless不管计算属性最终返回的是什么都直接进行渲染(少计算,多渲染)

写回答

2回答

ustbhuangyi

2020-03-15

你分析的配合代码呢?

0
5
小小奥
哦,原来是这样,明白了谢谢老师
2021-11-02
共5条回复

哈哈大笑x

提问者

2020-03-15

//img1.sycdn.imooc.com/szimg/5e6e010d093f8a3406320427.jpg

然后模板上显示的数据是name

0
0

Vue.js 源码深入解析 深入理解Vue实现原理

全方位讲解 Vue.js 源码,进阶高级工程师

4984 学习 · 1037 问题

查看课程