vue2:
数据代理:将data配置项中的数据代理到vm实例上
数据劫持:让data中的数据具有响应式(数据变,页面跟着变)
<script>
function Vue(options) {
let data = options.data;
// 数据代理
Object.keys(data).forEach((key) => {
Object.defineProperty(this, key, {
get() {
return data[key];
},
set(val) {
data[key] = val;
},
});
});
// 数据劫持
Object.keys(data).forEach((key) => {
defineReactive(data, key, data[key]);
});
}
function defineReactive(data, key, value) {
Object.defineProperty(data, key, {
get() {
return value;
},
set(val) {
value = val;
},
});
}
let vm = new Vue({
el: "#app",
data: {
msg: "Mr Fan",
},
});
</script>
vue3:
Proxy - ES6出的代理
参数一:源对象
参数二:配置的拦截器对象
通过 Proxy (代理): 拦截对象中任意属性的变化, 包括:属性值的读写、属性的添加、属性的删除等。
通过 Reflect(反射): 对源对象的属性进行操作。
<script>
let p1 = new Proxy(
{
name: "fan",
age: 18,
},
{
// 获取值
get(target, property) {
console.log("get -> ", target, property);
return Reflect.get(target, property);
},
// 设置值
set(target, property, value) {
console.log("set -> ", target, property, value);
Reflect.set(target, property, value);
},
// 删除
deleteProperty(target, property) {
console.log("deleteProperty", target, property);
return Reflect.deleteProperty(target, property);
},
has(target, property) {
console.log("拦截in操作");
return Reflect.has(target, property);
},
ownKeys(target) {
console.log("ownKeys -> ");
return Reflect.ownKeys(target);
},
}
);
console.log(p1);
console.log(p1.name);
p1.name = "ten";
delete p1.age;
console.log(p1);
console.log("name" in p1);
console.log(Object.keys(p1));
</script>
Object.defineProperty() 和 Proxy 区别:
Object.defineProperty() 是给某个对象下的某个属性,关注的是属性,新增删除属性,页面不会更新;
Proxy 关注的是对象,只要是这个对象下的属性都走 get 和 set