Vue2响应式原理

59 阅读2分钟

一.定义

Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象

二.语法

Object.defineProperty(参数一, 参数2, 参数三)

  • 参数一:要定义属性的对象
  • 参数二:要定义或修改的属性的名称
  • 参数三:要定义或修改的属性描述符

三.例子

最简单使用例子

   let person ={
            name:"sq",
            city:"成都",
        }
        Object.defineProperty(person,"age",{
            value:18,   
        })
   console.log(person.age);//输出为18 
   console.log(Object.keys(person));  //不能枚举(遍历)到age值
注意:通过Object.defineProperty()方法添加的属性默认不可以被遍历(枚举)

参数三里面有一些默认的配置属性为false

  1. enumerable:true,//控制属性是否可以枚举,默认为false
  2. writable:true,//控制属性是否可以被修改,默认为false
  3. configurable:true,//控制属性是否可以被删除,默认为false

四.Vue底层原理中使用

Vue中有数据代理的说法,那么什么是数据代理呢? 数据代理:通过一个对象代理对另一个对象中属性的操作

Vue中实现数据代理底层其实用的就是Object.defineProperty()方法 通过代码展示

 let hobby="敲代码"
    let person ={
        name:"sq",
        city:"成都",
    }
    Object.defineProperty(person,"hobby",{
        //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是hobby的值
        get:function(){
            return hobby
        },
        //当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
        set:function(value){
            hobby=value
        }
    })
    console.log(person)

一个简单的数据代理例子

 let obj1={x:1}
 let obj2={y:2}
        Object.defineProperty(obj2,'x',{
            get(){
                return obj1.x
            },
            set(value){
                obj1.x=value
            }
        })

总结实现原理:通过Object.defineProperty()把data对象中所有属性添加到vm上。 为每一个添加到vm上的属性,都指定一个getter/setter。 在getter/setter内部去操作(读/写)data中对应的属性。

五.Vue中的数据代理

 const vm= new Vue({
      el: "#root",
      data: {
          name:"清华大学",
          address:"北京",
      },
    });

注意:

  1. Vue中的数据代理通过vm对象来代理data对象中属性的操作
  2. Vue中数据代理的好处:更加方便的操作data中的数据