每当面试官问到Vue数据双向绑定原理的时候,我们都会简单的说:Vue 内部通过 Object.defineProperty 方法属性拦截的方式,把data 对象里每个数据的读写转化成 getter / setter,当数据变化时通知视图更新。虽然一句话把大概原理概括了,但是其内部的实现方式还是值得深究的,本文就以通俗易懂的方式剖析 Vue 内部双向数据绑定原理的实现过程
具体步骤需要几个重点:
1. 实现一个数据监听器 Observer,能够对数据对象的所有属性进行监听,如有变动可拿到最新值并通知订阅者
2. 实现一个指令解析器 Compile,对每个元素节点的指令进行扫描和解析,根据指令模板替换数据,并将每个指令对应的节点绑定更新函数,添加监听数据的订阅者,一旦数据有变动,收到通知,更新视图
3. 实现一个 Watcher,作为连接 Observer 和 Compile 的桥梁,能够订阅并收到每个属性变动的通知,执行指令绑定的相应回调函数,从而更新视图
4. 将 MVVM 作为数据绑定的入口,整合 Observer,Compile 和 Watcher 三者
简单的代码逻辑:
<body>//实现简单的双向绑定
<input type="text" id="inp">
<div id="demo"></div>
<script>
var demo = document.querySelector('#demo')
var inp = document.querySelector('#inp')
let obj = {}
inp.addEventListener('input', function(e) {
// 给 obj 的 name 属性赋值,进而触发该属性的 set 方法
obj.name = e.target.value
})
Object.defineProperty(obj, 'name', {
set: function(newVal) {
inp.value = newVal
demo.innerHTML = newVal
console.log('更新了obj的name:' + newVal) // name 属性值被修改时触发
},
get: function() {
console.log('获取obj数据name')
}
})
obj.name // 获取 data 数据 name
</script>
</body>