使用proxy以及Reflect还原vue3中的shallowReadonly 与 readonly响应式的原理

js实现

// 2 shallowReadonly 与 readonly


// 定义一个readonlyHandler处理对象
const readonlyHandler = {
    // 获取属性值
    get(target,prop){
        console.log('get',prop);
        const result = Reflect.get(target,prop)
        return result
    },
    // 修改属性或者说添加属性
    set(target,prop,value){
        console.log('不写',target);
        return true
    },
    // 删除某个属性
    deleteProperty(target,prop){
        console.log('不删',target);
        return true
    }
}

// 定义一个shallowReadonly函数
function shallowReadonly(target){
    // 需要判断当前数据是不是对象
    if(target&&typeof target =='object'){
        return new Proxy(target,readonlyHandler)
    }   
    return target
}

// 定义一个readonly函数
function readonly(target){
    // 需要判断当前数据是不是对象
    if(target&&typeof target =='object'){
        // // 判断target是不是数组
        if(Array.isArray(target)){
            // 遍历数组
            target.forEach((item,index)=>{
                target[index] = readonly(item)
            })
        }else{
            // 判断target是不是对象
            Object.keys(target).forEach(key=>{
                target[key]=readonly(target[key])
            })
        }
        return new Proxy(target,readonlyHandler)
    }   
    return target
}

测试

/ 2 测试shallowReadonly 与 readonly
        // 测试浅层只读对象
        const proxyUser3 = shallowReadonly({
            name:'小明',
            car:['奔驰','宝马']
        })
        // 可以读取浅层
        // console.log(proxyUser3.name);
        // 不可修改
        // proxyUser3.name = '小红'
        // 不可删除
        // delete proxyUser3.name
        // 浅层只读,拦截不了深度修改
        // 拦截到了读取,可修改
        // proxyUser3.car[0]='奥迪'
        // 拦截到了读取,可删除
        // delete proxyUser3.car[0]
        // console.log(proxyUser3);

        // 测试深度只读对象
        const proxyUser4 = readonly({
            name:'小明',
            car:['奔驰','宝马']
        })
        // 拦截到了读取
        // console.log(proxyUser4.name);
        // console.log(proxyUser4.car[0]);
        // 只读
        // proxyUser4.name = "小红"
        // proxyUser4.car[0] = "哈哈"
        // 不能删除
        delete proxyUser4.name
        delete proxyUser4.car[0]
posted @ 2021-04-16 14:08  xujing123  阅读(114)  评论(0编辑  收藏  举报