二十、双向绑定原理

双向绑定的原理也叫响应式原理,面试时候经常会问到。

1、Vue时采用对象设计模式发布者-订阅者模式的方式,通过Object.defineProperty()属性的setter,getter,在数据变动时

      发布消息给订阅者,触发相应的监听回调。来完成双向绑定。

2、Object.defineProperty()方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象

3、Object.defineProperty有三个参数

       1>第一个:需要定义属性的当前对象

       2>第二个:当前需要定义的属性名

       3>第三个:属性描述符

<!--步骤1、Object.defineProperty方法的使用。-->
<script>
    var data={};
    Object.defineProperty(data,'name',{
        get(){//获取值getter

        },
        set(val){//作用1:监听数据发生变化。作用2:设置值,setter。
            console.log(val);//输出结果:李四
        }
    });
    data.name='李四';
</script>
 <!--步骤2、调用windows的addEventListener方法,监听input元素,执行回调函数-->
<input type="text">
<script>
    window.addEventListener("input",function(e){ 
        console.log(e.target.value);//输出结果:输入框输入的值
    });
</script>
<!--步骤3、(结合步骤1和步骤2代码,)在步骤2中,把监听input元素后获取到的值,赋值步骤1中的data.name元素即可-->
<input type="text">
<script>
    var data={};
    Object.defineProperty(data,'name',{
        get(){},
        set(val){//监听data的name属性值是否发生改变,改变成什么值
            console.log(val);//输出的就是data的name属性值改变后的值
        }
    });
    window.addEventListener("input",function(e){
        data.name=e.target.value; //步骤3的关键是在这一句代码
    })
</script>
<!--步骤4、(在步骤3的基础上)增加一个span元素,把监听到的数据变化后的值,赋值给span元素的文本内容。这样就实现input元素内容改变,span元素内容也随之同步更新的效果。-->
<input type="text">
<span id="text"></span>
<script>
    var data={};
    Object.defineProperty(data,'name',{
        get(){},
        set(val){
            text.innerHTML=val;//把监听到数据变化后的值,赋值给span元素的文本内容。
        }
    });
    window.addEventListener("input",function(e){
        data.name=e.target.value;
    });
</script>
<!--尝试:在步骤4基础上,尝试获取数据变化后的data对象失败-->
<input type="text">
<span id="text"></span>
<script>
    var data={};
    Object.defineProperty(data,'name',{
        get(){},
        set(val){
            text.innerHTML=val;//把监听到数据变化后的值,赋值给span元素的文本内容。
        }
    });
    window.addEventListener("input",function(e){
        data.name=e.target.value;
        console.log(data)//输出结果:{name: undefined}。
                         //因为在Object.defineProperty中,没有返回变化后的新数据。所以在这里获取不到data对象的新数据。
    });
</script>
<!--步骤5、(在步骤4的基础上,)设置一个全局变量value,在set方法中把监听到数据变化后的值val赋值给value,再在get方法中返回value-->
    <input type="text">
    <span id='text'></span>
    <script>
        var data={};
        var value='';//关键1:设置全局变量
        Object.defineProperty(data,'name',{
            get(){
                return value;//关键3:返回全局变量。
            },
            set(val){
                text.innerHTML=val;
                value=val;//关键2:把监听到数据变化后的值,赋值给全局变量。
            }
        });
        window.addEventListener("input",function(e){
            data.name=e.target.value;
            console.log(data.name)
        })
    </script>

 

posted @ 2021-09-07 23:50  Strugglinggirl  阅读(1313)  评论(0编辑  收藏  举报