文章目录
一、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等,进而实现响应式
四、图示总结

本文详细解释了Vue中Object.defineProperty()方法的作用,介绍了数据代理的概念以及如何通过它操作数据。同时深入剖析了数据劫持在Vue中的应用,包括vm._data的来源和双向绑定的工作机制。
2178

被折叠的 条评论
为什么被折叠?



