Object.defineproperty方法 (数据劫持 数据代理 计算属性 都用到这个方法) 【p11】
Object.keys
Object.defineProperty(person, 'age', {
get() {
console.log('有人读取age属性了')
},
set(value) {
console.log('有人修改了age属性,且值是', value)
number = value
}
})
数据代理 【p13 有图】
<script>
let obj1 = {
x: 100
}
let obj2 = {
y: 200
}
Object.defineProperty(obj2,'x',{
get(){
return obj1.x;
},
set(value){
console.log(value,'value')
obj1.x = value;
}
})
</script>
vm身上的数据代理
data里面的变量都有自己的getter和setter
读取vm.name 触发vm身上name属性的getter调用
通过vm改的时候 vm.name = "新value" 触发vm身上name属性的setter方法调用
vm把数据存到自身身上 data.name访问不到 _data.name 访问的到 _data数据劫持
vm._data = options.data = data
即 vm._data === data 所以可以证明以上这个逻辑
如果vm没有数据代理那就要写成{{_data.name}} 因为有数据代理 所以直接可以{{name}}
读用getter 修改用setter
数据代理把 _data中的数据放到vm身上一份,更加方便可以直接访问vm.xxx 所以可以直接{{xxx}}
官方总结:
1.Vue中的数据代理:
通过vm对象来代理data对象中属性的操作(读/写)
2.Vue中数据代理的好处:
更加方便的操作data中的数据
3.基本原理:
通过Object.defineProperty()把data对象中所有属性添加到vm上。
为每一个添加到vm上的属性,都指定一个getter/setter。
在getter/setter内部去操作(读/写)data中对应的属性。
_data 数据劫持 实现响应式
为了让vue检测到_data中数据的改变,所以_data里面的结构又变了
不把事件写在data上,因为没有意义 给个setget就没意义vue会很累