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

js还原

// 1 shallowReactive 与 reactive
// 浅的劫持,浅的监视,浅的响应式数据 与 reactive(深度响应式)

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

// 定义一个shallowReactive函数,传入目标对象
function shallowReactive(target){
    // 判断当前的目标对象是不是object类型(对象/数组)
    if(target&&typeof target==='object'){
        return new Proxy(target,reactiveHandler)
    }
    // 如果传入的数据是基本类型数据 直接返回
    return target
}

// 定义一个reactive函数,传入目标对象
function reactive(target){
    // 判断当前的目标对象是不是object类型(对象/数组)
    if(target&&typeof target==='object'){

        // 对数组或者是对象中所有的数据reactive的递归处理

        // 先判断当前的数据是不是数组
        if(Array.isArray(target)){
            target.forEach((item,index)=>{
                target[index] = reactive(item)
            })
        }else{
        // 再判断当前的数据是不是对象
        // 对象数据也要进行遍历
            Object.keys(target).forEach(key=>{
                target[key] = reactive(target[key])
            })
        }

        return new Proxy(target,reactiveHandler)
    }
    // 如果传入的数据是基本类型数据 直接返回
    return target
}

引入测试

<script src="./index.js"></script>
   <script type="text/javascript">
    // 测试 浅响应式对象
    const proxyUser1 = shallowReactive({
        name:'小明',
        car:{
            color:'red'
        }
    })
    // 拦截到了读和写数据
    // proxyUser1.name += '小红'
    // 拦截到了读取数据,没有写数据,因为是浅响应
    // proxyUser1.car.color += '小红'
    // 拦截到了删除数据
    // delete proxyUser1.name
    // 拦截到读取拦截不到删除
    // delete proxyUser1.car.color
    // console.log(proxyUser1);

    // 测试深度响应式对象
    const proxyUser2 = reactive({
        name:'小明',
        car:{
            color:'red'
        }
    })
    // 拦截到了读和写
    // proxyUser2.name += '小红'
    // 拦截到了读和写
    // proxyUser2.car.color += '小红'
    // 拦截了删除
    // delete proxyUser2.name
    // 拦截到了读和删除
    // delete proxyUser2.car.color
    // console.log(proxyUser2);
</script>
posted @ 2021-04-12 14:31  xujing123  阅读(428)  评论(0编辑  收藏  举报