vue3手写 shallowReactive与reactive的劫持操作

vue3的响应式操作劫持

vue3响应式劫持操作主要用到了es6中的Proxy代理 与Reflect执行原有操作行为;

定义reactiveHandler处理对象 进行数据拦截

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

手写shallowReactive

//  定义一个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
}

检验

	 const proxyUser1 = shallowReactive({
    
    
            name: 'hhh',
            schoolRecord: {
    
    
                chinese: '88',
                english: "59",
                math: '99'
            }
        })
        // shallowReactive可以拦截读取数据
        proxyUser1.name;
        // shallowReactive可以拦截修改数据
        proxyUser1.name = '黎明';
        // shallowReactive可以拦截读取深层的数据 不可以拦截修改深层的数据
        proxyUser1.schoolRecord.chinese = '66';
        console.log('*********************################***********************');
        
        const proxyUser2 = reactive({
    
    
            name: 'zzz',
            schoolRecord: {
    
    
                chinese: '88',
                english: "59",
                math: '99'
            }
        })
        // reactive可以拦截读取数据
        proxyUser2.name;
        // reactive可以拦截修改数据
        proxyUser2.name = '黎明';
        // reactive可以拦截读取深层的数据 也可以拦截修改深层的数据
        proxyUser2.schoolRecord.chinese = '66';

在这里插入图片描述

测试完整代码

index.js

/*
 * @Descripttion: 
 * @version: 
 * @Author: HHH
 * @Date: 2021-02-22 16:04:04
 * @LastEditors: HHH
 * @LastEditTime: 2021-02-22 16:43:33
 */

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

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

index.html


<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="./index.js"></script>
</head>

<body>
    <script type="text/javascript">
        const proxyUser1 = shallowReactive({
    
    
            name: 'hhh',
            schoolRecord: {
    
    
                chinese: '88',
                english: "59",
                math: '99'
            }
        })
        // shallowReactive可以拦截读取数据
        proxyUser1.name;
        // shallowReactive可以拦截修改数据
        proxyUser1.name = '黎明';
        // shallowReactive可以拦截读取深层的数据 不可以拦截修改深层的数据
        proxyUser1.schoolRecord.chinese = '66';
        console.log('*********************################***********************');
        
        const proxyUser2 = reactive({
    
    
            name: 'zzz',
            schoolRecord: {
    
    
                chinese: '88',
                english: "59",
                math: '99'
            }
        })
        // reactive可以拦截读取数据
        proxyUser2.name;
        // reactive可以拦截修改数据
        proxyUser2.name = '黎明';
        // reactive可以拦截读取深层的数据 也可以拦截修改深层的数据
        proxyUser2.schoolRecord.chinese = '66';

    </script>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/weixin_43245095/article/details/113943842
今日推荐