数据代理:
概念:通过一个对象代理对另一个对象中属性的操作(读/写)。
基本原理:通过Object.defineproperty方法把data对象中的所有属性添加vm上,为每一个添加到vm上的属性指定getter和 setter方法,利用它去操作。
注意:Object.defineproperty方法添加属性,不可枚举,不可修改,不可删除。
属性:
-
enumerable属性控制属性是否可以枚举,就认为false
-
writable属性控制属性是否可以被修改,就认为false
-
configurable属性控制属性是否可以被删除,就认为false
例1:实现简单的数据代理
<script>
let obj={x:100}
let obj1={y:300}
Object.defineProperty(obj1,'x',{
// 当被读取时get函数(getter)被调,返回值是defineproperty添加的值
get(){
console.log("obj通过obj1被读取了");
return obj.x;
},
// 当被修改时 set函数(setter)被调,收到修改的具体值
set(value){
obj.x=value;
console.log("obj通过obj1被修改了");
}
})
</script>
运行结果:
解析:简单来说原理就是通过一个对象(obj1)操作另一个对象(obj)就是一个数据代理。这里利用Object.defineproperty方法通过obj1操作obj,利用get方法(即getter)调用和set方法(setter)修改obj中的x,从而实现数据代理。
例2:
<div id="app">
<h2>name:{{name}}</h2>
<h2>age:{{age}}</h2>
</div>
<script>
let data={
name:"小小",
age:18
}
const vm=new Vue({
el:'#app',
data//这里有三个全等vm._data=options.data=data
})
</script>
解析:vue的数据代理本质是把data中的数据放到vm上一份。vm._data===data结果为true可知data中的数据存储在_data中。这里就是通过_data操作data中的数据。