《Vuejs设计与实现》5.8.2 建立响应式联系

84 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第20天,点击查看活动详情

在上一篇文章中,我们讲了一下响应Set时的问题,再了解到为什么会出现问题,以及如何解决之后,我们可以着手开始响应一下Set了。

当我们访问size的时候,追踪一下依赖,那么,我们如何在修改Set的时候怎么样触发依赖呢。比如,我们调用add方法,向Set中插入元素,这时候size也应该变化。我猜,你们肯定想到了我们响应数组的时候,我们需要重写add方法去触发依赖。

const methods = {
 add(val){
     //这里的this还是proxy,这里不再需要bind,我们可以直接操作target
     const target = this.raw
     const res = target.add(val)
     trigger(target,val,'ADD')
     return res
 }
}
const s = new Proxy(new Set(),{
  get(target,key,receiver){
      /*省略其他逻辑*/
      if(getType(target) === 'set'){
      if(key === 'size'){ track(target, ITERATE_KEY) }
      if(key === 'add'){ return methods[key] }
       
      }
  }
}

在这里,我们重写了add方法,但是这样还有点不过,我们应该在修改一下add方法,略微优化一下.

 add(val){
     const target = this.raw
     if(!target.has(val)){
         const res = target.add(val)
         trigger(target,val,'ADD')
         return res
     }
 }

这时候,我们需要回忆一下trigger,那里面有一句逻辑,当type等于ADDDELETE的时候,才会使用ITERATE_KEY.

这时候,我们只需要照葫芦画瓢,再去实现其他方法就行了。这样就基本完成了Set的响应。

其实我们之前的代码比较散乱,但是如果你一页页阅读这本书,你才会发现作者为什么要这么做。有的时候,我们只需要掌握一些思路和方法,而不是具体的代码,如果你想看源码,你可以直接到vuejs的仓库里看。但是解决问题的思路却不好从源码里看到,通过作者一步一步的拆解,我们能发现当时设计vue框架的时候,开发团队都碰见了什么问题,有时候,我觉得能找到问题比发现问题更重要。

能找到问题,意味着你彻底了解了整个项目的逻辑,并且有着自己的实现思路,这才是我们应当从书中学的,而不是最后结果。就好比数学考试,计算结果并不比计算过程更重要。

下一章中,我们需要讲到避免污染原始数据,目的是为了解决某些情况下的多次执行副作用函数的问题