computed,watch

computed: 在初始化子组件构造器的时候,会判断是否有computed属性,然后如果有,就对其进行处理,将对应computed的属性设置在原型上,并且拦截了他的get为createComputedGetter返回值,在原型上定义是为了多组件共享

初始化执行init时,会执行initState,然后执行initComputed,然后创建一个watcher,然后将computed对用的函数传入,赋值给watcher的getter,然后把watcher放在vm._computedWatchers下

然后再render过程,会访问到对应的computed内定义的变量,由于最开始说了get被拦截,所以会走到createComputedGetter,首先我们会拿到初始化的时候定义的watcher

然后执行watcher.evaluate();求值,走到this.get(),然后首先执行pushTarget(this),将Dep.target改为computed Watcher,然后执行this.getter,即computed对应的函数,然后函数里会有对应的响应式变量,所以会走到对应的get逻辑,添加computed Watcher为他的订阅者

然后执行watcher.depend,往watcher里添加订阅者,即组件的渲染watcher

当数据发生变化时,会触发notify,通知变化,同之前,会走到watcher.run,执行this.get(),重新收集依赖等,然后判断值是否改变了,然后更新

watch: watch流程较为简单,初始化执行init时,执行initState,然后执行initWatcher,然后执行createWatcher逻辑,其实就是执行了一次vm.$watch,然后执行new Watcher,注意此时expOrFn可能是一个string,然后执行parsePath逻辑,将返回的函数赋值getter,然后有执行get,然后再去执行getter,执行getter会将vm传入,然后这个时候obj就是vm,所以后面会访问到obj上的变量,所以触发getter以来收集,由于之前执行get()时,Dep.target为userWatcher,所以就会收集这个userWatcher,然后变化的时候,在通知更新

 

function parsePath (path) {
  if (bailRE.test(path)) {
    return
  }
  var segments = path.split('.');
  return function (obj) {
    for (var i = 0; i < segments.length; i++) {
      if (!obj) { return }
      obj = obj[segments[i]];
    }
    return obj
  }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值