美文网首页
Vue双向数据绑定原理

Vue双向数据绑定原理

作者: 罂粟1995 | 来源:发表于2018-05-31 12:42 被阅读0次

    什么是双向数据绑定?

    Vue是个MVVM框架,当数据发生变化时,视图也跟着发生变化,当视图发生变化时,数据也会跟着同步变化。双向数据绑定,一般是对于UI控件来说的,非UI控件不会涉及到双向数据绑定。

    Vue双向数据绑定是怎么实现的?

    官方文档上说得很简单——用v-model指令在表单元素上创建双向数据绑定。


    屏幕快照 2018-05-31 上午7.43.43.png

    那么,v-model背后的实现原理又是什么呢?
    它的基本原理是利用Object.defineProperty()这个方法重新定义了对象获取属性值(get)和设置属性值(set)的操作来实现的。
    使用Object.defineProperty()实现一个简单的双向数据绑定小例子:

    <!doctype html>
    <html>
        <head>
            <title></title>
        </head>
        <body>
            <input id="text" type="text" />
            <p id="p"></p>
        </body>
        <script type="text/javascript">
            var obj = {};
            Object.defineProperty(obj,"name",{
                get:function(){
                    return name;
                },
                set:function(value){
                    document.getElementById("text").value = value;
                    document.getElementById("p").innerHTML = value;
                }
            });
            var input = document.getElementById("text");
            input.addEventListener("input",function(event){
                var text = event.target.value;
                obj.name = text;
            });
        </script>
    </html>
    

    效果:


    屏幕快照 2018-05-31 上午10.59.20.png

    可以看到,我们在输入框输入内容时,<p>标签内会显示对应的内容,这说明实现了model=>view的绑定。
    现在我们在控制台给obj.name赋值,发现赋值后输入框的内容变成了所赋的那个值:


    屏幕快照 2018-05-31 上午11.00.57.png

    说明实现了view=>model的绑定。

    当然vue的实现比这复杂得多,详细请查看网上大牛们的博客。

    这种实现双向数据绑定的方法叫作数据劫持结合发布者-订阅者模式。

    简单解释什么是数据劫持结合发布者-订阅者模式:
    1、数据劫持:在本例中,通过Object.defineProperty来劫持name属性的setter,getter,在数据变化时通知订阅者,触发相应的回调;
    2、发布者/订阅者:订阅者可定义为希望接收到通知的对象;发布者可定义为激活事件的对象。在本例中,文本输入框相当于一个订阅者,Obj相当于一个发布者。文本框通过addEventListener接收Obj给它的启动通知,触发相应的函数,进行视图更新。

    一般来说,实际应用中会涉及多个订阅者,这时就需要一个消息订阅器来管理这些订阅者;另外还需要指令来初始化订阅者。
    详情及更复杂的例子可参考这篇博文:
    http://www.cnblogs.com/libin-1/p/6893712.html

    相关文章

      网友评论

          本文标题:Vue双向数据绑定原理

          本文链接:https://www.haomeiwen.com/subject/ampfsftx.html