文章目录
一、Object.definePropety() 方法详解
二、数据代理
2.1. 什么是数据代理
数据代理(Data Proxy): 通过一个对象代理对另一个对象中属性的操作(读/写)
通过 obj2 (读/写) obj1 的属性:
let obj1 = {
x: 100,
}
let obj2 = {
y: 500,
}
Object.defineProperty(obj2, 'x', {
get() {
return obj1.x;
},
set(val) {
obj1.x = val;
}
})
2.2. Vue中的数据代理
const vm = new Vue({
data: {
message: "Hello, World!"
}
});
console.log(vm.message); // 通过数据代理访问vm实例的属性
vm.message = "你好" // 通过数据代理修改vm实例的属性
在上述示例中,
vm.messgae
实际上是访问了vm._data.message
vm._data
是data
通过数据劫持加工后的数据,vm._data === data
Vue中数据代理的好处
更加方便的操作数据,只需要vm.message
三、数据劫持
3.1. 什么是数据劫持
数据劫持: 是指在访问或修改对象的属性时,对这些操作进行拦截和监视,以便在属性发生变化时能够触发相关的操作。
3.2. Vue中的数据劫持
在 Vue 中,数据劫持用于监听数据的变化,以实现双向绑定和响应式更新。
当读写
vm.message
,会读写vm._data.message
,_data
怎么来的?
3.3. vm._data
怎么来的?
他是配置项中的
data
通过Object.defineProperty
加工之后而来
下面是
加工函数(Observer)
的简单实现,obs
就是加工后的实例对象,然后把加工后的obs
赋值给data
和vm._data
<script>
function Observer(obj) {
// 汇总对象中所有的属性形成一个数组
const keys = Object.keys(obj);
keys.forEach((key) => {
Object.defineProperty(this, key, {
get() {
return obj[key];
},
set(newVal) {
obj[key] = newVal;
console.log(
`${key}被改了,我要去解析模板,生成虚拟DOM.....我要开始忙了~`
);
},
});
});
}
let data = {
message: "Hello Vue!",
};
let vm = {};
// 创建一个监视的实例对象,用于监视data中属性的变化
const obs = new Observer(data);
// 把加工后的obs赋值给data和vm._data
vm._data = data = obs;
</script>
当修改了
vm.message
,会触发vm
身上的message的setter
,去修改vm._data
的message
,然后就会触发vm._data
身上的message的setter
,这个setter
去负责解析模板,生成虚拟DOM等,进而实现响应式