Vue双向数据绑定原理-上
Vue响应式的原理(数据改变界面就会改变)是什么?
时时监听数据变化, 一旦数据发生变化就更新界面, 这就是Vue响应式的原理。
Vue是如何实现时时监听数据变化的
通过原生JS的defineProperty方法, 通过get和set方法来监听数据的变化。
defineProperty方法的特点
可以直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回这个对象。
defineProperty用法
?> 可以直接在一个对象上定义一个新属性
假设我有这么一个需求,给obj对象动态新增一个name属性, 并且name属性的取值必须是BNTang,通过 defineProperty 方法实现。
<script>
let obj = {};
Object.defineProperty(obj, 'name', {
value: 'BNTang'
});
console.log(obj);
</script>
defineProperty 是属于 Object 对象的方法,所以我们可以直接通过 Object.defineProperty 来调用。
- 第一个参数是要定义属性的对象(obj: 需要操作的对象)
- 第二个参数是要定义或修改的属性的名称(prop: 需要操作的属性)
- 第三个参数是将被定义或修改的属性描述符(descriptor: 属性描述符)
最终语法如下:
Object.defineProperty(obj, prop, descriptor)
在上面提出的需求中,我们需要动态新增一个 name 属性,所以第一个参数就是 obj 对象,第二个参数就是 name 属性,第三个参数就是 name 属性的描述符。
我在第三个参数中定义了一个 value 属性,这个 value 属性的值就是 BNTang,这样我们就实现了动态新增一个 name 属性,并且 name 属性的值是 BNTang。
value 属性描述符的作用可以通过value来告诉defineProperty方法新增的属性的取值是什么。
!> 默认情况下通过defineProperty新增的属性的取值是不能修改的。
<script>
let obj = {};
Object.defineProperty(obj, 'name', {
value: 'BNTang'
});
obj.name = 'test';
console.log(obj);
</script>
如果想修改, 那么就必须显示的告诉defineProperty方法,这个属性是可修改的,通过writable属性描述符来实现。
<script>
let obj = {};
Object.defineProperty(obj, 'name', {
value: 'BNTang',
writable: true,
});
obj.name = 'test';
console.log(obj);
</script>
!> 默认情况下通过defineProperty新增的属性是不能删除的。
<script>
let obj = {};
Object.defineProperty(obj, 'name', {
value: 'BNTang',
writable: true,
});
obj.name = 'test';
delete obj.name;
console.log(obj);
</script>
如果想删除, 那么就必须显示的告诉defineProperty方法,这个属性是可删除的,通过configurable属性描述符来实现。
<script>
let obj = {};
Object.defineProperty(obj, 'name', {
value: 'BNTang',
writable: true,
configurable: true,
});
obj.name = 'test';
delete obj.name;
console.log(obj);
</script>
!> 默认情况下通过defineProperty新增的属性是不能遍历(迭代的)。
<script>
let obj = {};
Object.defineProperty(obj, 'name', {
value: 'BNTang'
});
for (let key in obj) {
console.log(key, obj[key]);
}
</script>
如果想迭代, 那么就必须显示的告诉defineProperty方法,这个属性是可迭代的,通过enumerable属性描述符来实现。
<script>
let obj = {};
Object.defineProperty(obj, 'name', {
value: 'BNTang',
enumerable: true
});
for (let key in obj) {
console.log(key, obj[key]);
}
</script>
到此为止,定义一个新属性的方法就介绍完了,接下来我们来看看如何修改一个对象的现有属性。
其实非常的简单,只需要在我们定义对象的时候初始化一个属性,并且给这个属性一个初始值,然后在调用 defineProperty 方法的时候,将这个属性的值修改为我们想要的值就可以了。
代码如下:
<script>
let obj = {name: 'Example'};
Object.defineProperty(obj, 'name', {
value: 'BNTang'
});
console.log(obj);
</script>