Vue的响应式原理主要利用Object.defineProperty()对数据进行劫持,实现数据的响应式。
原理如下:
- 在初始化阶段,Vue会遍历data中的属性,使用Object.defineProperty()把这些属性全部转为getter/setter。
- 在getter中,Vue会追踪依赖,在setter中触发依赖的更新。
- 这样一来,当数据变化触发setter时,Vue能够精确知道哪些数据依赖于该属性,从而作出精确更新。
例如,我们有一个示例数据:
js
data: {
name: 'TOM',
age: 20
}
Vue在初始化时将进行如下操作:
js
var data = {
name: 'TOM',
age: 20
}
var dep = new Dep() // 依赖收集容器
Object.defineProperty(data, 'name', {
enumerable: true,
configurable: true,
get: function() {
dep.depend() // 通知dep添加订阅者watcher
return name
},
set: function(newVal) {
name = newVal
dep.notify() // 通知dep中的订阅者
}
})
// 给age属性也同样设置getter和setter
...
当我们更新data.name
,会触发set
方法,该方法会通知dep
调用订阅者的update
方法进行更新操作。
js
// 更新name
data.name = 'Jack'
// 此时dep会通知所有的订阅者
dep.notify()
// 订阅者收到通知并更新
watcher.update()
所以响应式的核心就是:
- 通过Object.defineProperty()对属性进行劫持。
- 在getter中收集依赖,在setter中触发依赖的更新。
- 由于订阅者会在依赖更新时更新视图,所以实现了数据变化导致视图变化的响应式效果。
这就是Vue在响应式数据和视图更新之间的关联关系,使得我们可以通过操作数据来驱动视图的更新。
网友评论