Vue3响应式原理(Proxy(obj,{get(){},set(){}}))

Vue3原理:首先是get方法分析,再者set方法分析,最后双向数据绑定,层层渐进到掌握,以及与Vue2的区别,话不多说,直接上代码分析。

1、Proxy响应式的get方法,

<!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>
        let obj = {
            name:"Vue",
            age:8
        }
        // Proxy 代理  new Proxy()创建一个代理对象
        // new Proxy(要代理的这个对象,{get(),set()})

        let obj2 = new Proxy(obj,{
            get(target,property){
                // 什么时候执行? 当我们访问 obj2 的某个属性的时候
                // target和 property 表示什么?
                // target 是这个obj对象 ,property就是我们访问的这个属性
                console.log("执行了get",target,property);
                return target[property]

            }
        })
        console.log(obj2.age);
        console.log(obj2.name);
        // obj2 是一个代理对象,属性和值的obj一样
    </script>
</head>
<body>
    
</body>
</html>

执行效果

2、Proxy响应式的set方法

 <script>
        let obj = {
            name:"Vue",
            age:8
        }
        // Proxy 代理  new Proxy()创建一个代理对象
        // new Proxy(要代理的这个对象,{get(),set()})

        let obj2 = new Proxy(obj,{
            get(target,property){
                // 什么时候执行? 当我们访问 obj2 的某个属性的时候
                // target和 property 表示什么?
                // target 是这个obj对象 ,property就是我们访问的这个属性
                console.log("执行了get",target,property);
                return target[property]

            },
            set(target,property,newVal){
                // 数据劫持的时候 执行这里的代码   newVal就是 boj2.age = 9  =号 后面的这个值
                console.log("执行了set",target,property,newVal);

                // 在这里进行修改这个属性成为新的值,下次访问,才能拿到新值
                target[property] = newVal

            }
        })
        obj2.age = 9;  //修改值 触发执行了set
        console.log(obj2.age)
         
        
        /*
            自己总结:
            1:obj2.age = 9;  //修改值 触发执行了set   就会执行set里面的console.log   newVal=9 但是实际return是8没有改到
            2:在set里面修改值 才会变 才真正改了

            
        */

    </script>

效果图:

3、双向数据绑定

<body>
    <input type="text" id="ipt">
    <p id="op"></p>
    <script>

        let obj = {
            txtVal : "初始值"
        }

        function myReactive(obj){
            return new Proxy(obj,{
                get(target,property){
                    return target[property]
                },
                set(target,property,newVal){
                    // 对象劫持  数据劫持
                    ipt.value = newVal
                    op.innerHTML = newVal
                    target[property] = newVal
                }
            })
        }

        let objRet = myReactive(obj);

        // 绑定初始值
        ipt.value = objRet.txtVal;
        op.innerHTML = objRet.txtVal

        
        ipt.addEventListener("input",e=>{
            objRet.txtVal = e.target.value  //触发了set
        })

    </script>
</body>

效果图:

4、Vue2和Vue3set的区别

Vue3的set修改值

<script>
        let obj = [10,20,30]

        let obj2 = new Proxy(obj,{
            get(target,property){
                console.log("执行了get",target,property);
                return target[property]

            },
            set(target,property,newVal){
                console.log("执行了set",target,property,newVal);
            }
        })
        obj2[0] = 1000
         
        /*
            对比:
                Vue2 将初始值改为数组,在下面就修改不了了  而且触发不了set
                Vue3 就可以 

        */ 
    </script>

如图:

Vue2的set修改值(修改不了)

<body>

    <input type="text" id="oipt">
    <p id="op"></p>

    <script>
        let obj = {};
        // let val = "默认值";
        let = [10,20,30]

        Object.defineProperty(obj,"iptVal",{
            get(){
                return val;
            },
            set(newVal){
                oipt.value =newVal
                op.innerHTML = newVal
                // val = newVal
            }
        })
        // 设置初始值
        oipt.value = obj.iptVal;
        op.innerHTML = obj.iptVal;

        oipt.addEventListener("keyup",function(e){
            // 发布者,影响订阅者的
            obj.iptVal[0] = e.target.value  //触发了set
        })

    </script>
</body>

效果图:set 就修改不到

猜你喜欢

转载自blog.csdn.net/xfy991127/article/details/134722963