前情提要
在vue2的方法中,对于对象和数组的修改
- 对象:
通过 this.对象.属性 = xxx 是不能实现页面响应的,但是数据确实修改了。
可以通过this.$set(修改的对象,修改的属性,改为什么值) 修改对象的某个属性值,
通过 this.$delete(删除的对象,删除的属性)来删除对象中某个属性
- 数组:
通过 this.数组[下标] = xxx 是不能实现页面响应的,但是数据确实修改了。
可以通过 this.$set(修改的数组, 下标, 修改的值) 来修改数组中某个下标所在元素的值,
通过 数组.splice(开始的索引, 替换的数量, 替换的内容) 可以把数组某个位置之后的值都替换为某个值
Object.defineProperty 方法
Object.defineProperty:vue 的数据代理,数据劫持,计算属性的底层都是这个方法。
let person = {
name:'哈喽喔',
sex:'male'
}
Object.defineProperty(person,'age',{
value:22
})
console.log(person);
// 遍历对象方式一 for in
for (const key in person) {
console.log(key,':',person[key]);
}
//遍历对象方式二 keys方法
console.log(Object.keys(person));
其中
Object.defineProperty(person, 'age' ,{ value:29 })
就是把age属性加到person对象中,age的属性值为29
Object.keys(person)
就是将person对象中存在的 属性名 放到数组中,函数返回这个数组
最后遍历这个对象
结果:
可见遍历person时没有打印出age,所以
通过defineProperty加入到对象中的属性默认是不会被遍历出来的(不可遍历)
enumerable
只需要在defineProperty方法的最后一个参数的对象中加入属性,enumerable: true 即可遍历加入的属性,
Object.defineProperty(person,'age',{
value:22,
enumerable: true //控制属性是否可以被枚举,默认值 false
})
writable
通过writable: true 控制属性可以被修改
Object.defineProperty(person,'age',{
value:22,
writable: true //控制属性是否可以被修改,默认值 false
})
configurable
通过configurable: true 控制属性可以被删除
Object.defineProperty(person,'age',{
value:22,
configurable: true //控制属性是否可以被删除,默认值 false
})
get() 和 set()
let number = 22 // 数据代理
let person = {
name:'哈喽喔',
sex:'male'
}
Object.defineProperty(person,'age',{
// value:22
get(){
console.log('有人读取了age属性');
return number
},
set(value){
console.log('有人修改了age属性,且值为'+value);
number = value
}
})
console.log(person);
打印person对象可见
鼠标悬停在三个小点上时候,提示invoke property getter 即调用属性getter方法,点击时执行上面defineProperty中的get()
点击之后,调用执行defineProperty中配好的get()方法,得到number对应值
通过控制台修改age的值之后再次获取,调用执行get()方法可以看到,值被修改了↓
这样就实现了数据代理。