vue数据代理原理[双向绑定原理]

Vue
413
0
0
2022-10-14

来源

尚硅谷Vue2.0+Vue3.0全套教程丨vuejs从入门到精通

数据代理

通过vm对象来代理data对象中属性的操作(读/写)

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

认识Object.defineProperty

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

  let  person = {
        name:'张三',
        sex:'男',
        //age:18
    }
    //不可枚举(不被遍历) 
    Object.defineProperty('person','age',{
        value:18
    })
    console.log(Object.keys(person));

    //配置可以枚举 
    Object.defineProperty('person','age',{
        value:18,
        enumerable:true,//控制属性是否可以被枚举,默认false 
        writable:true,//控制属性是否可以被修改,默认false(默认不可以修改age的值) 
        configurable:true,//控制属性是否可以被删除,默认false(默认不可以删除age的值`delete person.age`)
    })
    console.log(Object.keys(person));

高级用法

    let number = 18 
    let  person = {
        name:'张三',
        sex:'男'
    }
    Object.defineProperty('person','age',{
        //当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值 
        get(){
            console.log("有人读取了age属性")
            return number
        },
        //当有人修改person的age属性时,set函数(setter)就会被调用,且收到修改的具体值 
        set(value){
            console.log("有人修改了age属性,且值是",value)
            number = value
        },
    })

实例详解

<!DOCTYPE html>
<html lang="en">

<head> 
    <meta charset="UTF-8"> 
    <title>数据绑定</title>
</head>

<body> 
    <div id="app"> 
        <div>{{name}}</div> 
    </div> 
    <script src="./vue.js"></script> 
    <script> 
        Vue.config.productionTip = false //阻止vue在启动时生成生产提示 
        const vm = new Vue({
            el: "#app",
            data: {
                name: "数据绑定",
            },
        })
    </script>
</body>

</html>
  1. console.log(vm)

vue数据绑定原理

通过Object.defineProperty()把data对象中所有属性添加到vm上。
为每一个添加vm上的属性都指定一个getter/setter
  1. vm._data === options.data # true
{
 el: "#app",
 data: {
     name: "数据绑定",
 },
}
  1. vm.name = "修改数据绑定了"
在getter/setter内部去操作(读/写)data中对应的属性
执行过程 vm.name => setter => data
vue数据代理原理
vue数据代理原理
  1. vm._data.name = "恢复数据绑定了"
  2. {{name}} 等于 {{_data.name}}
  3. {{name}}等于读取(getter)_data.name
  4. _data不是数据代理而是数据劫持
  5. vue数据代理原理