vue3手写 shallowReadonly与readonly的劫持操作

vue3的响应式操作劫持

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

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

// 定义 readonlyHandler 处理函数
const readonlyHandler = {
    
    
    get(target, prop) {
    
    
        const result = Reflect.get(target, prop);
        console.log('拦截到了读取数据', prop, result);
        return result
    },
    set(target, prop, value) {
    
    
        console.warn("只能读取数据,不能修改数据或者添加数据");
        return true;
    },
    deleteProperty(target, prop) {
    
    
        console.log('只能读取数据,不能删除数据');
        return true;
    }
}

手写shallowReadonly

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

    return target
}

手写readonly

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

        }
        return new Proxy(target, readonlyHandler)
    }
    // 如果不是对象或者数组 自己返回
    return target
}

检验

       const proxyUser1 = shallowReadonly({
    
    
            name: 'hhh',
            schoolRecord: {
    
    
                chinese: '88',
                english: "59",
                math: '99'
            }
        })
        // shallowReadonly 可以读取数据
        proxyUser1.name;
        // shallowReadonly 不能修改数据
        proxyUser1.name = '核酸';
        // shallowReadonly 不能删除数据
        delete proxyUser1.name;
        console.log('########操作深层数据#########');
        // shallowReadonly 可以读取深层的数据
        proxyUser1.schoolRecord.math;
        // shallowReadonly 可以修改深层的数据
        proxyUser1.schoolRecord.math = '100';
        // shallowReadonly 可以删除深层的数据
        delete proxyUser1.schoolRecord.math

        console.log('*********************################***********************');

        const proxyUser2 = readonly({
    
    
            name: 'zzz',
            schoolRecord: {
    
    
                chinese: '88',
                english: "59",
                math: '99'
            }
        })

        // readonly 可以读取数据
        proxyUser2.name;
        // readonly 不能修改数据
        proxyUser2.name = '核酸';
        // readonly 不能删除数据
        delete proxyUser2.name;
        console.log('########操作深层数据#########');
        // readonly 可以读取深层的数据
        proxyUser2.schoolRecord.math;
        // readonly 不可以修改深层的数据
        proxyUser2.schoolRecord.math = '100';
        // readonly 不可以删除深层的数据
        delete proxyUser2.schoolRecord.math

在这里插入图片描述

测试完整代码

index.js

/*
 * @Descripttion: 
 * @version: 
 * @Author: HHH
 * @Date: 2021-02-22 17:12:08
 * @LastEditors: HHH
 * @LastEditTime: 2021-02-22 17:37:42
 */
// 定义 readonlyHandler 处理函数
const readonlyHandler = {
    
    
    get(target, prop) {
    
    
        const result = Reflect.get(target, prop);
        console.log('拦截到了读取数据', prop, result);
        return result
    },
    set(target, prop, value) {
    
    
        console.warn("只能读取数据,不能修改数据或者添加数据");
        return true;
    },
    deleteProperty(target, prop) {
    
    
        console.log('只能读取数据,不能删除数据');
        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);
            })
        }
        // 判断target是否是对象
        else {
    
    
            // 遍历对象
            Object.keys(target).forEach(key => {
    
    
                target[key] = readonly(target[key]);
            })

        }
        return new Proxy(target, readonlyHandler)
    }
    // 如果不是对象或者数组 自己返回
    return target
}

index.html

<!--
 * @Descripttion: 
 * @version: 
 * @Author: HHH
 * @Date: 2021-02-22 16:04:16
 * @LastEditors: HHH
 * @LastEditTime: 2021-02-22 17:42:13
-->
<!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 = shallowReadonly({
    
    
            name: 'hhh',
            schoolRecord: {
    
    
                chinese: '88',
                english: "59",
                math: '99'
            }
        })
        // shallowReadonly 可以读取数据
        proxyUser1.name;
        // shallowReadonly 不能修改数据
        proxyUser1.name = '核酸';
        // shallowReadonly 不能删除数据
        delete proxyUser1.name;
        console.log('########操作深层数据#########');
        // shallowReadonly 可以读取深层的数据
        proxyUser1.schoolRecord.math;
        // shallowReadonly 可以修改深层的数据
        proxyUser1.schoolRecord.math = '100';
        // shallowReadonly 可以删除深层的数据
        delete proxyUser1.schoolRecord.math

        console.log('*********************################***********************');

        const proxyUser2 = readonly({
    
    
            name: 'zzz',
            schoolRecord: {
    
    
                chinese: '88',
                english: "59",
                math: '99'
            }
        })

        // readonly 可以读取数据
        proxyUser2.name;
        // readonly 不能修改数据
        proxyUser2.name = '核酸';
        // readonly 不能删除数据
        delete proxyUser2.name;
        console.log('########操作深层数据#########');
        // readonly 可以读取深层的数据
        proxyUser2.schoolRecord.math;
        // readonly 不可以修改深层的数据
        proxyUser2.schoolRecord.math = '100';
        // readonly 不可以删除深层的数据
        delete proxyUser2.schoolRecord.math

    </script>
</body>

</html>

猜你喜欢

转载自blog.csdn.net/weixin_43245095/article/details/113946000