美文网首页
vue响应式涉及到的基础知识(简单易懂)

vue响应式涉及到的基础知识(简单易懂)

作者: meng_281e | 来源:发表于2020-01-18 10:56 被阅读0次
    响应式原理:

    vue.js 则是采用数据劫持结合发布者-订阅者模式的方式,通过Object.defineProperty()来劫持各个属性的setter,getter,在数据变动时发布消息给订阅者,触发相应的监听回调。

    1.搞清楚什么是Object.defineProperty

    Object.defineProperty():直接在一个对象上定义一个新属性,或者修改一个已经存在的属性。

    Object.defineProperty(object ,propertyname,descriptor )
    接收三个参数

    • object (要修改的对象)

    • propertyname (属性名)

    • descriptor (属性描述)
      1、value 属性的值,
      2、writable 是否可操作属性值 ,
      3、configurable 是否可修改配置
      4、enumerable 是否可枚举

      image.png

    2.defineProperty的get与set

    • getter :是一种获得属性值的方法
    • setter:是一种设置属性值的方法。
    var obj = {},book = '三国演义';
    
    Object.defineProperty(obj,'book',{
        get: function(){
          //返回经过处理后的变量
            return '<<'+book+'>>'
        },
        set: function(val){
        //利用临时变量接收赋值
            book = val
       }    
    })
    
    console.log(obj.book) ==> "<<三国演义>>"
    
    obj.book = '西游记'
    
    console.log(obj.book) ==> "<<西游记>>"
    

    3.数据变化,vue如何视图更新的

    数据更改 ---->get进行依赖收集,找到哪些组件数据更改----> Set触发Notify ----> 更改对应的虚拟DOM ----> 重新render
    image.png

    4.什么是观察者

    一种实现一对多关系解耦的行为设计模式。

    它主要涉及两个角色:观察目标、观察者。如图:

    image

    特点:观察者 要直接订阅 观察目标,观察目标 做出通知后,观察者 就要进行相应处

    5.什么是依赖收集

    也就是被依赖者要知道依赖者的存在
    const obsObject = observable({
        A: 1,
        B: 2,
        C: 3
    });
    
    autoRun(() => {
        console.log(obsObject.A + obsObject.C);
        console.log(obsObject.C - obsObject.A);
    });
    
    obsObject.B = 4; // 什么都没有发生
    obsObject.A = 5;
    //  --> 8   observe函数的回调触发了
    //  --> -2   observe函数的回调触发了
    obsObject.C = 6;
    //  --> 11   observe函数的回调触发了
    //  --> 1   observe函数的回调触发了
    

    依赖收集:通过自然地使用变量,来完成依赖的收集,当变量改变时,根据收集的依赖判断是否需要触发回调。
    Object.defineProperty实现方式:

    //定义一个对象
    const hero ={
      name: '赵云',
      hp: 3000,
      sp: 150,
      equipment: ['马', '矛']
    };
    //创建观察
    class Observable {
      constructor(obj) {
        return this.walk(obj);
      }
    
      walk(obj) {
        const keys = Object.keys(obj);
        keys.forEach((key) => {
          this.defineReactive(obj, key, obj[key]);
        })
        return obj;
      }
    
      defineReactive(obj, key, val) {
        if (Array.isArray(obj[key])) {
          // Array添加push的钩子
          Object.defineProperty(obj[key], 'push', {
            value() {
              this[this.length] = arguments[0];
            }
          })
          Object.defineProperty(obj, key, {
            get() {
              return val;
            }
          })
        } else {
          Object.defineProperty(obj, key, {
            get() {
              return val;
            },
            set(newVal) {
              val = newVal;
            }
          })
        }
      }
    }
    

    通过defineReactive函数对数据对象“英雄”的各属性get与set设置了钩子,在get中响应依赖收集,在set中触发监听函数,至此该数据对象变得“可观察”。
    观察者

    Watcher(hero, 'health', () => {
      return hero.hp > 2000 ? '强壮' : '良好';
    });
    

    相关文章

      网友评论

          本文标题:vue响应式涉及到的基础知识(简单易懂)

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