vue.js最初的數據綁定實驗解析

正文:

源碼來源於vuejs的commit記錄:a5e27b1174e9196dcc9dbb0becc487275ea2e84cjavascript

做者在getset-revits-style.htmlgetset.html中簡單實驗了一下數據綁定。html

模板vue

<div id="test">
        <p>{{msg}}</p>
        <p>{{msg}}</p>
        <p>{{msg}}</p>
        <p>{{what}}</p>
        <p>{{hey}}</p>
    </div>

jsjava

var app = new Element('test', {
        msg: 'hello'
    })

和vue官網的例子幾乎一毛同樣。下面來看下實現源碼,我以爲能夠分爲如下幾個點:git

  1. 獲取須要進行數據綁定的domgithub

    var self     = this,
        el = self.el = document.getElementById(id)
  2. 模板解析替換,做者經過正則/\{\{(.*)\}\}/g來找到那些被{{}}標記的地方,而且替換成帶有標記的span標籤, 而後將這些標記存在bindings中。app

    var bindingMark = 'data-element-binding'
    var content  = el.innerHTML.replace(/\{\{(.*)\}\}/g, markToken)
    
    function markToken (match, variable) {
        bindings[variable] = {}
        return '<span ' + bindingMark + '="' + variable +'"></span>'
    }
    
    el.innerHTML = content
  3. 利用Object.defineProperty劫持數據來進行數據綁定dom

    for (var variable in bindings) {
        bind(variable)
    }
    
    function bind (variable) {
        bindings[variable].els = el.querySelectorAll('[' + bindingMark + '="' + variable + '"]')
        ;[].forEach.call(bindings[variable].els, function (e) {
            e.removeAttribute(bindingMark)
        })
        Object.defineProperty(data, variable, {
            set: function (newVal) {
                [].forEach.call(bindings[variable].els, function (e) {
                    bindings[variable].value = e.textContent = newVal
                })
            },
            get: function () {
                return bindings[variable].value
            }
        })
    }

    首先遍歷bindings中的標記,而且在bindings中記錄帶有標記的DOM節點,而後遍歷節點將標記刪除,最後就是劫持data中對應的屬性了。
    關於Object.defineProperty的原理不做贅述,咱們只看看他set和get都分別做了什麼。this

    set: 遍歷含有當前標記的節點, 把新值賦值給當前dom的e.textContent,並在bindings中對應標記裏記錄這個值。spa

    get: 直接獲取內存中存儲的值。


clipboard.png



相關文章
相關標籤/搜索