欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

vue的双向数据绑定(Object.defineProperty(),和es6的Proxy的底层封装是Object.defineProperty()封装的);...

程序员文章站 2022-07-12 22:49:13
...
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<div id="app">
    <!--在vue中以v-开头,放在行间属性具有特殊意义的一些指令-->
    <input type="text" v-model="abc">
    <div v-model="abc"></div>
    {{abc}}
</div>
<script src="node_modules/vue/dist/vue.js"></script>
<script>
    let vm = new Vue({
        el:"#app",
        data:{
            // vue 将遍历这个data中所有的属性名,并使用Object.defineProperty这个方法;当获取属性名对应的属性值时,会默认走get方法,设置会执行set方法;
            // data中属性也会放到实例上;
            // 视图-->数据;采用了DOM监听机制;当数据发生变化,会触发那些订阅者;
            abc:"201815"
        }
    })
    //
    for(let key  in  data){
        Object.defineProperty(data,key,{
            get(){

            },
            set(){
            }
        })
    }

    // 1. 视图可以影响数据,数据可以改变视图;
    let  obj = Object.defineProperty({},"name",{
        get(){
            // 当获取obj的属性名name时,会触发该get方法
            console.log(100);
            return 100;
        },
        set(){
            // 当设置属性名name时,就会触发set方法;
            console.log(200);
        }
    })
    //console.log(obj.name);
    obj.name =1;
</script>
</body>
</html>
复制代码

双向数据绑定原理

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="text" id="box">
<script>
    let box = document.getElementById("box");
    let  obj = {};
    let temp ={}
    Object.defineProperty(obj,"name",{
        get(){
            // 在get方法中,不能调用自己的属性名对应的属性值;
            return temp.name;
        },
        set(val){
            // val : 代表的是将要设置的最新的值;是等号右边的值;
            //console.log(obj);
            console.log(box.value);
            //debugger
            temp.name=val;
            box.value = val;
        }
    });
    // 修改input的内容;改变数据中的name属性值;
    box.addEventListener("input",function () {
        // 监听box的input事件;当修改box的输入框内容时,同时修改数据中name属性;
        obj.name = this.value;
    })
</script>
</body>
</html>
复制代码

自己理解双向数据绑定

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<input type="text" id="inp">
<script>
    var inp=document.getElementById('inp');
    let obj={};
    let temp={};
    Object.defineProperty(obj,'b',{
        get(){
            console.log(100);//input框发生变化的时候,会触发get方法
            //return obj.b;//如果用obj.b的话会导致栈溢出,所以我们用第三方变量去处理
            console.log(temp.b);//初始时undefined
            return temp.b;

        },
        set(val){
            //temp.b=val;//如果不给temp.a赋值val的话,get获取的值是undefined
            console.log(temp.b);
            inp.value=val;
        }
    });
    inp.addEventListener('inp',()=>{
        obj.b=this.value;//获取input框最新的内容的值,然后把input框最新的值赋值给obj.b
    })
</script>
</body>
</html>
复制代码

Proxy底层是用Object.defineProperty()封装的

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script>
    //Proxy:代理器;对对象架设了一层拦截;当获取对象中键值对时,必须经过这层拦截;可以对外界访问进行过滤和拦截
    var obj=new Proxy({a:1,b:2},{
        get:function (target,key,reciver) {
            //当获取obj下a属性名对应的属性值时,会触发get方法
            //如果想获取目标target属性名对应的属性值,需要在get中将其属性值return出去
            //console.log(target[key]);
            //console.log(key);
            //console.log(reciver);//返回的是new Proxy()的第一个参数
            console.log('get');
            return target[key];
        },
        set:function () {
            //当设置当前对象下属性名的属性值就会触发set方法
            console.log('set');
        }
    });
    console.log(obj);//obj是传的第一个参数
    console.log(obj.a);
    console.log(obj.b);
    obj.a='111222';//设置的时候就会触发set函数
</script>
</body>
</html>
复制代码

转载于:https://juejin.im/post/5c8f6833e51d45168e30e299