vue3手写 shallowRef与ref的劫持操作

vue3的响应式操作劫持

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

因为当参数为数组或者对象时 ref相当于reactive;所以要定义reactive;

定义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
    }
 }

手写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
}

手写shallowRef

function shallowRef(target) {
    
    
    return {
    
    
        // 保存target数据保存起来
        _value: target,
        get value() {
    
    
            console.log('劫持得到了读取数据');
            return this._value
        },
        set value(value) {
    
    
            console.log("劫持到了修改数据,",
                value);
                this._value = value;
        }
    }
}

手写ref

// 定义一个ref函数
function ref(target) {
    
    
    target =  reactive(target);
    return {
    
    
        // 保存target数据保存起来
        _value: target,
        get value() {
    
    
            console.log('劫持得到了读取数据');
            return this._value
        },
        set value(value) {
    
    
            console.log("劫持到了修改数据,",
                value);
                this._value = value;
        }
    }
}

检验

  const proxyUser1 = shallowRef({
    
    
            name: 'hhh',
            schoolRecord: {
    
    
                chinese: '88',
                english: "59",
                math: '99'
            }
        })
        // shallowRef 可以读取数据
        console.log(proxyUser1.value);
        console.log('********************************************');
        // 不可以 劫持修改深层数据
        proxyUser1.value.name = '哈哈';
        console.log('********************************************');
        // shallowRef 可以修改浅层数据
        proxyUser1.value = '哈哈';


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

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

        // ref 可以读取数据
        console.log(proxyUser2.value);
        console.log('********************************************');
        // 可以 劫持修改深层数据
        proxyUser2.value.name = '哈哈';
        console.log('********************************************');
        // ref 可以修改浅层数据
        proxyUser2.value = '哈哈';

在这里插入图片描述

测试完整代码

index.js

/*
 * @Descripttion: 
 * @version: 
 * @Author: HHH
 * @Date: 2021-02-22 17:12:08
 * @LastEditors: HHH
 * @LastEditTime: 2021-02-23 11:24:59
 */
//  定义一个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
    }
 }
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
}


// 定义一个sallowRef函数
function shallowRef(target) {
    
    
    return {
    
    
        // 保存target数据保存起来
        _value: target,
        get value() {
    
    
            console.log('劫持得到了读取数据');
            return this._value
        },
        set value(value) {
    
    
            console.log("劫持到了修改数据,",
                value);
                this._value = value;
        }
    }
}

// 定义一个ref函数
function ref(target) {
    
    
    target =  reactive(target);
    return {
    
    
        // 保存target数据保存起来
        _value: target,
        get value() {
    
    
            console.log('劫持得到了读取数据');
            return this._value
        },
        set value(value) {
    
    
            console.log("劫持到了修改数据,",
                value);
                this._value = value;
        }
    }
}

index.html


<!--
 * @Descripttion: 
 * @version: 
 * @Author: HHH
 * @Date: 2021-02-22 16:04:16
 * @LastEditors: HHH
 * @LastEditTime: 2021-02-23 11:24:44
-->
<!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 = shallowRef({
    
    
            name: 'hhh',
            schoolRecord: {
    
    
                chinese: '88',
                english: "59",
                math: '99'
            }
        })
        // shallowRef 可以读取数据
        console.log(proxyUser1.value);
        console.log('********************************************');
        // 不可以 劫持修改深层数据
        proxyUser1.value.name = '哈哈';
        console.log('********************************************');
        // shallowRef 可以修改浅层数据
        proxyUser1.value = '哈哈';


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

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

        // ref 可以读取数据
        console.log(proxyUser2.value);
        console.log('********************************************');
        // 可以 劫持修改深层数据
        proxyUser2.value.name = '哈哈';
        console.log('********************************************');
        // ref 可以修改浅层数据
        proxyUser2.value = '哈哈';
    </script>
</body>

</html>

猜你喜欢

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