Vue 源码学习心得
记录下Vue源码阅读的心得,从git上下载到代码,从最初代码开始阅读.
1.Vue数据绑定
<div id="app'>
<span>{{msg}}</span>
<span>{{hello}}</span>
<span>{{world}}</span>
</div>
new Vue({
el:'app',
data:{
msg:'hello Wolrd',
hello:'你好!',
}
})
此处实现双向绑定的原理:
function Vue(opt){
const bindingMark = 'data-element-binding'
//在此id范围的html元素才能实现双向绑定
var item = document.getElementById(opt.el);
content = el.innerHTML.replace(/\{\{(.*)\}\}/g, markToken);
el.innerHTML = content;//此处以替换成 <span data-element-binding='msg'> </span> <span data-element-binding='hello'> </span> <span data-element-binding='world'> </span>
//重点发生在bingding函数中
for(variable in bindings){
bind(variable);
}
if (opt.data) {
for (var variable in opt.data) {
data[variable] = opt.data[variable]
}
//标签进行替换,并删除标记 <some-mark>{{some}}<some-mark> ⇒ <some-mark data-element-bindings='some'><some-mark>
function markToken (match, variable) {
bindings[variable] = {}
return '<span ' + bindingMark + '="' + variable +'"></span>'
}
//查找本参数所对应的所有node节点,并将bindings缓存数组中的els替换为查找出来的nodeList,查找完毕将对应节点的bindingMark移除,此时binding数据中存在的数据为 [msg:{els:nodesList},hello:{els:nodeList},world:{els:[]}]
function bind (variable) {
bindings[variable].els = el.querySelectorAll('[' + bindingMark + '="' + variable + '"]')
;[].forEach.call(bindings[variable].els, function (e) {
e.removeAttribute(bindingMark)
})
//主要数据绑定起作用源于此,set函数可以观察到数据变化,数据变化后找到替换后的所有元素,并将值替换成需要绑定的值,以此来实现数据绑定,只要数据变化,更新所有绑定的元素
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
}
})
}
}
心得
Vue数据实现绑定主要为数据替换,原理为将"<span>{{params}}<span>"
符号替换为类似与 <span data-element-bindings='params'><span>形式,
然后通过Object.define 来定义属性,添加数据变化的观察器,实现对应元素的
实时更新