详解vue的数据binding原理

Posted luohaonan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了详解vue的数据binding原理相关的知识,希望对你有一定的参考价值。

请看原文:

草席两个页面:

<!DOCTYPE html>
<html>
    <head>
        <title>ideal</title>
        <meta charset="utf-8">
    </head>
    <body>
        <div id="test">
            <p>{{msg}}</p>
            <p>{{msg}}</p>
            <p>{{msg}}</p>
            <p>{{what}}</p>
            <p>{{hey}}</p>
        </div>
        <script>
            var bindingMark = data-element-binding
            function Element (id, initData) {
                var self     = this,
                    el          = self.el = document.getElementById(id)
                    bindings = {} //内部暂存绑定数据及dom
                    data      = self.data = {} //存储bingding数据并实现监控
                    content  = el.innerHTML.replace(/{{(.*)}}/g, markToken)
                    el.innerHTML = content
                 
                for (var variable in bindings) {
                    bind(variable); //将每个数据的名称比如‘msg‘绑定到data
                }
                if (initData) {
                    for (var variable in initData) {
                        data[variable] = initData[variable]
                    }
                }
                function markToken (match, variable) {
                    bindings[variable] = {} //bindings里存储了数据来源的字段比如bindings[‘msg‘]
                    return <span  + bindingMark + =" + variable +"></span>
                }
                function bind (variable) {
                    bindings[variable].els = el.querySelectorAll([ + bindingMark + =" + variable + "])//bindings里再存储msg绑定的元素
                    ;[].forEach.call(bindings[variable].els, function (e) { //删除data-element-binding属性
                        e.removeAttribute(bindingMark)
                    })
                    Object.defineProperty(data, variable, { //es5观察属性
                        set: function (newVal) {
                            [].forEach.call(bindings[variable].els, function (e) {
                                bindings[variable].value = e.textContent = newVal //=>这里才是实现的绑定,更新数据到dom并更新内部暂存数据
                            })
                        },
                        get: function () {
                            return bindings[variable].value  //取数据仅仅是内部暂存的数据
                        }
                    })
                }
            }
            
            var app = new Element(test, {
                msg: hello,
                what: hi
            })

        </script>
    </body>
</html>

 


 

 

<!DOCTYPE html>
<html>
    <head>
        <title>ideal</title>
        <meta charset="utf-8">
    </head>
    <body>
        <input class="test" type="text" name="asd" onkeyup ="handleChange()" v-model="hey">
        <input class="test" type="" name="" onkeyup ="handleChange()" v-model="msg">
        <script>
            var bindingMark = data-element-binding
            function Element (classa, initData) {
                var self     = this,
                    el          = self.el = document.getElementsByClassName(classa),//多个input改为class
                    bindings = {} 
                    data      = self.data = {} 
                    for (var i = 0; i < el.length; i++) {
                        content  = el[i].outerHTML.replace(/v-model="(.*)"/g, markToken);
                        el[i].outerHTML = content
                    }
                for (var variable in bindings) {
                    bind(variable); 
                }
                if (initData) {
                    for (var variable in initData) {
                        data[variable] = initData[variable]
                    }
                }
                function markToken (match, variable) {
                    bindings[variable] = {} 
                    return  bindingMark + =" + variable +" //内填一个span变为只改它的元素
                }
                function bind (variable) {

                    bindings[variable].els = document.querySelectorAll([ + bindingMark + =" + variable + "])//document获取binding元素
                    ;
                    Object.defineProperty(data, variable, { 
                        set: function (newVal) {
                            [].forEach.call(bindings[variable].els, function (e) {
                                bindings[variable].value = e.value = newVal //=>textContent改为input的value
                            })
                        },
                        get: function () {
                            return bindings[variable].value 
                        }
                    })
                }
            }
            
            var app = new Element(test, {
                msg: hello,
                hey:aaa
            })
            function handleChange(e){ //增加v=>m的绑定
                e = e || window.event
                var key = e.target.outerHTML.match(/data-element-binding="(.*)"/)[1];
                data[key] = e.target.value
                console.log(data.hey,data.msg);
            }
        </script>
    </body>
</html>

 

 

以上是关于详解vue的数据binding原理的主要内容,如果未能解决你的问题,请参考以下文章

解vue的数据binding原理(转)

Vue2从入门到精通详解Vue数据双向绑定原理及手动实现双向绑定

Vue数据绑定原理及简单实现

Vue过滤器filter和filters的使用详解

12.VUE - v-bind 详解

基于Vue2.0数据双向绑定原理-详解