美文网首页
vue源码赏析四(数据响应式)

vue源码赏析四(数据响应式)

作者: 梦行乌托邦 | 来源:发表于2020-06-22 18:05 被阅读0次
    1. 找到处理数据响应的代码
      initMixinsrc/core/instance/index.js
      ----------->
      initStatesrc/core/instance/init.js
      ----------->
      initDatasrc/core/instance/state.js
      img1
      img2

    1:取data,如果data选项是函数,则取出该函数返回的值。

    2: 判断data是否是纯对象,不是的话重置为空对象,在非生产环境提供提示

    3:判断data中的键是否是 methodsprops中的键,如果是的话,在非生产环境提供提示

    4:如果data中的键不是以“$”或“_”开头(官方规则,避免冲突),则调用 proxy(vm, `_data`, key),作用看如下示例

    const vm = new Vue({data: {a: 'aa'}})
    

    这里 vm.a 能取到值,或修改 a 的值,都是通过以上proxy代理实现的,直接去 vm._data 操作。

    5:真正处理响应的地方

    1. observe(data, true) (src/core/observe/index.js)
      img3
      创建 Observer 实例并返回
      img4
      将Observe实例添加到vue实例的 data.__ob__
      img5
      如上两图,如果data是对象,则遍历各key调用 defineReactive,如果是数组,则递归调用 observe 方法
    1. 响应式核心代码 defineReactive(obj, keys[i]) (src/core/observe/index.js)
      img6
      这里可以看出,Vue数据响应式主要是通过 Object.defineProperty(get+set) 来实现的,这里面用到了 Dep,我们先看看 Dep 是什么
      src/core/observe/dep.js
      img7
      Dep类有一个静态属性target,用来存放 watcher;subs用来存放 watcher 数组;depend 方法为 watcher 调用 addDep来存放Dep的实例,notify 为派发更新,将 subs 中存放的 watcher 一个个拿出来调用 update 方法重新设值。由此可知,Dep是配合Watcher来实现依赖收集及更新的。让我们来看看Watcher里面有些什么
      src/core/observe/watcher.js
      img8
      这个类代码有点多,看 addDep 方法,可知watcher的newDeps存放了dep,dep的subs存放了watcher。依赖更新方法 update 调用了 queueWatchersrc/core/observer/scheduler.js
      img9
      这里主要是将需要更新的watcher收入队列,待执行。真正执行更新的方法在 nextTick(flushScheduQueue)src/core/util/next-tick.js
      img10
      了解了Dep和Watcher,再来看img6
      在获取data属性值时,先判断Dep.target是否有值,有值的话,让watcher关联dep,再就是子对象和数组的处理
      看下set
      img11
      修改值后dep调用notify方法派发更新

    写得很乱,dep和watcher的关系还是有点懵!参考下下面这条资料

    https://www.cnblogs.com/jiayiyi/p/12443976.html

    关于observe、dep、watcher在下篇文章再详细说明吧~

    相关文章

      网友评论

          本文标题:vue源码赏析四(数据响应式)

          本文链接:https://www.haomeiwen.com/subject/axfxfktx.html