vue数据绑定
vue2
// vue2.0,defineProperty拦截数组。
// 数组劫持。
let oldProtoMethods = Array.prototype;
let proto = Object.create(oldProtoMethods);
['push','pop','shift','unshift'].forEach(method => {
Object.defineProperty(proto,method,{
get(){
update();
oldProtoMethods[method].call(this,...arguments)
}
})
})
function observer(target){
if(typeof target !== 'object'){
return target
}
if(Array.isArray(target)){
Object.setPrototypeOf(target,proto);
for(let i = 0; i < target.length; i++){
observer(target[i])
}
return
};
for(let key in target){
defineReactive(target,key,target(key))
}
}
function update() {
console.log('更新')
}
function defineReactive(obj, key, value) {
observer(value); //对象多层,递归劫持。
Object.defineProperty(obj, key, {
// 注释部分为数据描述符。get,set为存取描述符,两者不可混用。
// configurable:false,//默认为false,控制是否可以通过重新定义属性的方式,可以更改,删除属性。
// writable:false,//默认false,控制是否可以通过赋值的方式改变属性值,当configurable为false,writable为真,仍可修改。
// enumerable:false,//默认为false,控制对象属性是否可枚举。
get() {
return value
},
set(newVal) {
if (newVal !== value) {
observer(value);
update();
}
}
})
}
let obj = {hobby:[{name:'youxuan'},'喝']}
observer(obj)
obj.hobby[0].name = 'webyouxuan'; // 更改数组中的对象也会触发试图更新
console.log(obj)
vue3
/**
* vue3.0 Proxy监听整个对象,还有数组
*
*/
// 代理对象
let proxyObj = new Proxy({}, {
get: (target, key, receiver) => {
console.log(`getting:${key}~`);
return target[key];
},
set: (target, key, value, receiver) => {
console.log(target, key, value, receiver);
return target[key] = value;
}
})
proxyObj.val = 1;
console.log(proxyObj.val);
// 代理数组
let proxyArr = new Proxy([], {
get: (target, key, receiver) => {
console.log(`getting:${key}~`);
return target[key];
},
set: (target, key, value, receiver) => {
console.log(target, key, value, receiver);
return target[key] = value;
}
})
proxyArr[0] = 2;
console.log(proxyArr[0]);