【vue】vue2+vue3数据监听

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]);
上一篇:Vue2基础面试总结


下一篇:vue2 与 vue3 项目的区别