在 Vue.js 中,双向数据绑定是通过数据劫持与发布者-订阅者模式实现的。
实现双向数据绑定的步骤:
- 使用 Object.defineProperty() 将对象的属性转换为 getter/setter。
js
function defineReactive(data, key, val) {
Object.defineProperty(data, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter() {
return val
},
set: function reactiveSetter(newVal) {
val = newVal
}
})
}
- 在 getter 中收集依赖,在 setter 中触发依赖更新。
js
let dep = [] // 依赖集合
function defineReactive(data, key, val) {
let dep = new Dep()
Object.defineProperty(data, key, {
get: function reactiveGetter() {
// 收集依赖
dep.depend()
return val
},
set: function reactiveSetter(newVal) {
if (val === newVal) return
val = newVal
// 触发依赖更新
dep.notify()
}
})
}
- 模板编译时将解析出的依赖推送给相应的 dep。
js
function compile(node) {
// 解析模板,获取依赖 key
let key = parse(node.textContent)
node.textContent = val[key]
// 收集依赖
dep.depend()
}
- 当数据改变触发 setter 时,dep 将通知所有依赖更新视图。
以上就是 Vue.js 双向数据绑定的实现原理。通过 getter/setter 收集依赖与触发更新,配合发布者-订阅者模式, elegant 地实现了数据与视图的绑定。