vue基础(二):Object.defineproperty方法&数据代理&数据劫持实现响应式

166 阅读2分钟
Object.defineproperty方法 (数据劫持 数据代理 计算属性 都用到这个方法) 【p11】
Object.keys
Object.defineProperty(person, 'age', {
// value:18,
// enumerable:true, //控制属性是否可以枚举,默认值是false
// writable:true, //控制属性是否可以被修改,默认值是false
// configurable:true //控制属性是否可以被删除,默认值是false

//当有人读取person的age属性时,get函数(getter)就会被调用,且返回值就是age的值
get() {
    console.log('有人读取age属性了')
    // return number	
},

//当有人修改person的age属性时,set函数(setter)就会被调用,且会收到修改的具体值
set(value) {
    console.log('有人修改了age属性,且值是', value)
    number = value
}

})
数据代理 【p13 有图】
<script>
let obj1 = {
    x: 100
}
let obj2 = {
    y: 200
}
// 通过obj2能读到x并且能修改x
Object.defineProperty(obj2,'x',{
    get(){
        return obj1.x; // 那么obj2.x可以读取到obj1.x
    },
    set(value){
        console.log(value,'value')
        obj1.x = value; // 修改obj2.x的时候 就把obj2.x的值改为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会很累