Vue中的数据代理
Object.defineProperty方法
这个方法是给一个对象添加属性用的,是es6的方法。
<script>
let person = {
name:'kunkun',
sex:'男',
}
Object.defineProperty(person,'age',{
value:'18'
})
console.log(person);
</script>
运行打开控制台,可以看到如下结果:
可以发现上面的age
属性的颜色比其它属性的颜色更淡,说明该属性是不参与枚举的,也就是不参与遍历。当我们用Object.keys(person)
遍历时,不会出现age
属性。如下图:
Q:想要该属性加入枚举该怎么做呢?
A:在配置项里加入enumerable
属性并将其值设为true
即可。
Object.defineProperty(person,'age',{
value:'18',
enumerable:true,//控制属性是否可以枚举,默认为false
})
Q:想要该属性能够被修改该怎么做呢?
A:在配置项里加入writable
属性并将其值设为true
即可。
Object.defineProperty(person,'age',{
value:'18',
enumerable:true,//控制属性是否可以枚举,默认为false
writable:true,//控制该属性是否可以被修改,默认为false
})
Q:想要该属性能够被删除该怎么做呢?
A:在配置项里加入configurable
属性并将其值设为true
即可。
Object.defineProperty(person,'age',{
value:'18',
enumerable:true,//控制属性是否可以枚举,默认为false
writable:true,//控制该属性是否可以被修改,默认为false
configurable:true,//控制该属性是否可以被删除,默认为false
})
有这样一个需求,我有一个number变量,然后person对象有一个age属性,且该属性的值是来源于number变量。用Object.defineProperty
方法,当number值更改时,age属性自动更改,该怎么做呢?如下代码:
<script>
let number = 18
let person = {
name:'kunkun',
sex:'男',
}
Object.defineProperty(person,'age',{
get(){
console.log('读取到的age属性值为:',number);
return number
},
//当修改person的age属性时,getter函数会被调用,且会收到修改的值
set(value){
console.log('修改了age属性值为:',value);
number = value
}
})
console.log(person)
</script>
结果如下:
理解数据代理
数据代理:通过一个对象代理对另一个对象中属性的操作(读/写),先上一个简单的例子:
<script>
//数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)
//通过obj2读取到obj的x并且能够修改x的值
let obj = {x:100}
let obj2 = {y:200}
Object.defineProperty(obj2,'x',{
get(){
return obj.x
},
set(value){
obj.x= value
}
})
</script>
在控制台进行一顿操作后,运行结果如图:
如上图所示我们通过obj2对象修改掉了obj对象中的x属性对应的值。 这就是一个简单的数据代理。
Vue中的数据代理
数据代理如下图图示,这里直接用了尚硅谷讲课的图,相关章节在这里。
其实Vue中的_data就近似于我们在写Vue实例时配置的data属性(_data中还有很多属性,是Vue内部用来做数据处理等操作的相关属性),vm用_data来取到我们在data中设置的值,比如vm._data.name
的值就和vm.name
的值是一模一样的。vm就相当于是一个数据代理。Vue中的数据代理能够更加方便的操作data中的数据。
Vue中数据代理的基本原理:
- 通过
Object.defineProperty()
把data对象中所有的属性添加到vm上。- 为每个添加到vm上的属性指定一个getter和setter函数。
- 在getter和setter内部去操作(读/写)data中对应的属性。
转载自:https://juejin.cn/post/7276407803618508839