美文网首页vue原理
Vue响应式原理Observer、Dep、Watcher理解

Vue响应式原理Observer、Dep、Watcher理解

作者: FConfidence | 来源:发表于2020-03-27 22:47 被阅读0次

    Vue响应式原理Observer、Dep、Watcher理解

    1. Observer
    • Observer是用来给数据添加Dep依赖。
    class Observer {
      constructor() {
        // 响应式绑定数据通过方法
        observe(this.data);
      }
    }
    
    export function observe (data) {
      const keys = Object.keys(data);
      for (let i = 0; i < keys.length; i++) {
        // 将data中我们定义的每个属性进行响应式绑定
        defineReactive(obj, keys[i]);
      }
    }
    
    1. Dep 管理依赖
    • Dep是data每个对象包括子对象都拥有一个该对象, 当所绑定的数据有变更时, 通过dep.notify()通知Watcher。

    • Dep就是帮我们收集【究竟要通知到哪里的】。

      <div>
        <p>{{message}}</p>
      </div>
      
      data: {
        text: 'hello world',
        message: 'hello vue',
      }
      
      1. 虽然data中有text和message属性,但是只有message被渲染到页面上,至于text无论怎么变化都影响不到视图的展示,因此我们仅仅对message进行收集即可,可以避免一些无用的工作。
      2. 当使用watch属性时,也就是开发者自定义的监听某个data中属性的变化。比如监听message的变化,message变化时我们就要通知到watch这个钩子,让它去执行回调函数。,第二个依赖就是用来管理watch中message变化的。
      3. 这个时候message的Dep就收集到了两个依赖
        • 依赖1: data中message的变化
        • 依赖2: watch监听message的变化
      watch: {
        message: function (val, oldVal) {
          console.log('new: %s, old: %s', val, oldVal)
        },
      }    
      
      1. 开发者自定义computed计算属性时,如下 messageTransfer 属性,是依赖message的变化的。因此message变化时我们也要通知到computed,让它去执行回调函数。 这个时候message的Dep就收集到了三个依赖,这个依赖就是用来管理computed中message变化的。

        computed: {
          messageTransfer() {
            return this.message.split('').reverse().join('');
          }
        }
        
      2. 图示如下:一个属性可能有多个依赖,每个响应式数据都有一个Dep来管理它的依赖。

        image.png
    1. Watcher
    • Watcher是连接Observer和Compile的桥梁,Compile解析指令时会创建一个对应的Watcher并绑定update方法 , 添加到Dep对象上。

    Dep 如何收集依赖

    1. Object.defineProperty
      function defineReactive (obj, key, val) {
        let Dep; // 依赖
      
        Object.defineProperty(obj, key, {
          enumerable: true,
          configurable: true,
          get: () => {
            console.log('我被读了,我要不要做点什么好?');
            // 被读取了,将这个依赖收集起来
            Dep.depend(); // 本次新增
            return val;
          },
          set: newVal => {
            if (val === newVal) {
              return;
            }
            val = newVal;
            // 被改变了,通知依赖去更新
            Dep.notify(); // 本次新增
            console.log("数据被改变了,通知所有的wather去调用update!");
          }
        })
      }
      

    什么是依赖 ? (Watcher)

    1. Watcher就是类似观察者的角色,比如message就有三个观察者,当message变化,就通知这三个观察者,他们就去执行各自需要做的变化 watcher.update()。

    2. 可以推测出,Watcher必须要有的2个方法。一个就是通知变化,另一个就是被收集起来到Dep中去。

      class Watcher {
        addDep() {
          // 我这个Watcher要被Observer塞到Dep里去了~~
        },
        update() {
          // Dep通知我更新呢~~
        }, 
      }
      

    总结

    1. Vue响应式原理的核心就是Observer、Dep、Watcher。

    2. Observer中进行响应式的绑定,在数据被读的时候,触发get方法,执行Dep来收集依赖,也就是收集Watcher。

    3. 在数据被改的时候,触发set方法,通过对应的所有依赖(Watcher),去执行更新。比如watch和computed就执行开发者自定义的回调方法。

    相关文章

      网友评论

        本文标题:Vue响应式原理Observer、Dep、Watcher理解

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