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

2016-06-05  本文已影响303人  lizhihua

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

上一篇下一篇

猜你喜欢

热点阅读