数据代理
Object.defineProperty方法
首先介绍一下Object.defineProperty。该方法传入三个参数。第一个参数为需要修改的对象,第二个参数为需要修改的属性,第三个属性为配置项,配置项的主要内容有以下几个:
1.value:这个用来设定属性值
2.enumerable:这个用来控制属性是否可以枚举,它的默认值时false。需要枚举时可设置为true。
3.writable:这个用来控制属性是否可以修改,默认值也是false。
4.configurable:这个用以控制属性是否可以被删除,默认值为false。
5.get():当有人读取设定对象的设定属性时,get函数(getter)就会被调用。
6.set():当有人修改设定对象的设定属性时,set函数(setter)就会被调用。
为了更好的了解Object.defineProperty方法的使用,附上实例如下所示
<body>
<script type="text/javascript" >
let number = 25
let person = {
name:'Revin',
sex:'男',
}
// 利用bject.defineProperty方法设定age属性以及属性值。
Object.defineProperty(person,'age',{
value:25,
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
}
})
</script>
</body>
何为数据代理
经过上述bject.defineProperty方法的介绍,实际上为了展示set()以及get()。
数据代理简单来讲就是通过一个对象代理对另一个对象中属性的操作(读/写),要想实现这种效果,就要利用bject.defineProperty方法中的get()与set()。
举例来说,如果想要实现利用Revin2对象来修改Revin1对象的age的话,就可以通过以下代码实现。
<body>
<!-- 数据代理:通过一个对象代理对另一个对象中属性的操作(读/写)-->
<script type="text/javascript" >
let Revin1= {age:25}
let Revin2 = {}
Object.defineProperty(Revin2,'age',{
get(){
return Revin1.age
},
set(value){
Revin1.age = value
}
})
</script>
</body>
具体运行结果如下
通过结果可以发现Revin2对象成功实现了对Revin1对象age的读写功能,即在Revin2对象上实现了对Revin1对象的数据代理。
Vue中的数据代理
通过上面的两小段实例,可以大概了解到数据代理的含义。
1.Vue中的数据代理:
通过vm对象来代理data对象中属性的操作(读/写)
2.Vue中数据代理的好处:
更加方便的操作data中的数据
3.基本原理:
通过Object.defineProperty()把data对象中所有属性添加到vm上。
为每一个添加到vm上的属性,都指定一个getter/setter。
在getter/setter内部去操作(读/写)data中对应的属性。
举一个简单的例子。我们可以通过对vm.name 和vm.age对页面内容进行修改,修改的原理就用到了数据代理。具体细节如下:
1.vm中的data数据添加到vm._data中。此处(还未进行数据代理),但是我们通过之前对Vue的了解知道,我们可以调用vm.age、vm.name。之所以能这么调用是因为第二步的数据代理
2.在vm中添加age与name。当要读取age时,利用get()去读_data中的age的数据,当要改age时,利用set()去改_data中的age数据。因此我们在书写时才可以省略_data这一步。(使用了数据代理)具体实验代码与运行结果以及流程图如下所示。
实验代码:
<body>
<div id="demo">
<!-- 不用数据代理的书写方式
<h2>名字:{{_data.name}}</h2>
<h2>年龄:{{_data.age}}</h2> -->
<h2>名字:{{name}}</h2>
<h2>年龄:{{age}}</h2>
</div>
<script type="text/javascript">
const vm = new Vue({
el: '#demo',
data: {
name: 'Revin',
age: '26'
}
})
</script>
</body>
运行结果:
流程图:
此处流程图引用尚硅谷的数据代理流程图。