通过访问 代理对象的属性 来间接访问 目标对象的属性。数据代理机制的实现需要依靠:Object.defineProperty()方法。
注意:代理对象新增的这个属性的名字 和 目标对象的属性名要一致,这样我们访问代理对象属性,就像在访问目标对象的属性一样
示例代码
<script>
// 目标对象
let target = {
name: "zhangsan",
};
// 代理对象
let proxy = {};
// 如果要实现数据代理机制的话,就需要给proxy新增一个name属性。
Object.defineProperty(proxy, "name", {
get() {
console.log("getter方法执行了@@@@");
// 间接访问目标对象的属性
return target.name;
},
set(val) {
target.name = val;
},
});
</script>
数据代理时对属性名的要求
1. Vue实例不会给以_和$开始的属性名做数据代理。
2. 为什么?
如果允许给_或$开始的属性名做数据代理的话。 vm这个Vue实例上可能会出现_xxx或$xxx属性, 而这个属性名可能会和Vue框架自身的属性名冲突。
3. 在Vue当中,给data对象的属性名命名的时候,不能以_或$开始。
示例代码
<body>
<!-- 容器 -->
<div id="app">
<h1>{{msg}}</h1>
</div>
<!-- vue程序 -->
<script>
const vm = new Vue({
el: "#app",
data: {
msg: "Hello Vue!",
_name: "zhangsan", //不会做数据代码,vm上看不到
$age: 20,//不会做数据代码,vm上看不到
},
});
</script>
</body>
模拟实现数据代理
简单实现myvm.name==options.data.name
示例代码
<script>
const myvm = new MyVue({
data: {
msg: "Hello Vue!",
name: "jackson",
age: 30,
},
});
</script>
数据代理js
示例代码
// 实现数据代理,目的是读取 myvm.name == options.data.name
// 定义一个Vue类
class MyVue {
// 定义构造函数
// options 是一个对象{}
// options对象中有一个data配置项
constructor(options) {
Object.keys(options.data).forEach((propertyName, index) => {
Object.defineProperty(this, propertyName, {
get() {
// 读取对象的属性值 对象[变量]
return options.data[propertyName];
},
set(val) {
options.data[propertyName] = val;
},
});
});
}
}