美文网首页
Vue.js早期源码阅读(一)

Vue.js早期源码阅读(一)

作者: lizhihua | 来源:发表于2016-06-05 10:22 被阅读303次

    Vue.js 早期源码阅读(版本号a5e27b1174e9196dcc9dbb0becc487275ea2e84c),关于ViewModel的一点分析

    <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 = {} // the internal copy
                data     = self.data = {} // the external interface
                content  = el.innerHTML.replace(/\{\{(.*)\}\}/g, markToken)
    
            el.innerHTML = 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 '<span ' + bindingMark + '="' + variable +'"></span>'
            }
    
            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
                    }
                })
            }
        }
        
        var app = new Element('test', {
            msg: 'hello'
        })
    
    </script>
    

    笔记:
    此段代码摘自vue.js在20130729提交记录的getset.html(871ed91)
    看下Vue.js的概述(http://cn.vuejs.org/guide/overview.html

    mvvm.png

    对照图片和图片下面的说明文字,我们知道:
    1.<div id="test"></div>中的内容就是View
    2.var app = new Element()创建出来的实例对象,是ViewModel
    3.{msg: 'hello'},是Model

    View和Model如何建立联系?就在于Element<function>。

    下面我们来逐步分析Element函数
    self指向new创建出来的实例,也就是ViewModel
    binding记录绑定关系
    data记录数据

    1.#test的content在开始的时候,把{{}}的内容,替换为具有data-element-binding指令的DOM元素

    content = el.innerHTML.replace(/\{\{(.*)\}\}/g, markToken)
    el.innerHTML = content
    

    2.bind函数处理每个插值variable

    bindings[variable].els记录所有data-element-binding=variable的元素,这样就把插值variable和DOM元素建立了绑定关系;
    此时指令data-element-binding已经没有用了,删除;
    定义每个插值的getter和setter,setter中遍历绑定的元素,赋值给元素的textContent
        bindings[variable].value = e.textContent = newVal
    

    3.遍历传入的数据,对应设置data的值,此时会触发getter和setter

    相关文章

      网友评论

          本文标题:Vue.js早期源码阅读(一)

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