Vue之Dep和Observer的用法及说明
什么是Dep
Dep(Dependence)是 Vue.js 内部实现响应式的核心。
Dep负责维护和管理所有的Watcher对象,所有被观察者(即响应式数据)的get函数中都会收集自己的依赖(Dep对象)到自己的dep中。
Dep的实现
Dep类的定义如下:
class Dep {
constructor () {
this.subs = []
}
addSub (sub) {
this.subs.push(sub)
}
removeSub (sub) {
remove(this.subs, sub)
}
depend () {
if (window.target) {
window.target.addDep(this)
}
}
notify () {
// stabilize the subscriber list first
const subs = this.subs.slice()
for (let i = 0, l = subs.length; i < l; i++) {
subs[i].update()
}
}
}
Observer 的实现
Observer 将一个对象上的所有属性转化为 getter/setter 的形式,以便“响应式”系统可以侦测到属性的读取和修改事件。当一个响应式数据被访问时(即执行get方法时),Dep会自动把当前的Watcher对象添加到自己的subs数组中,等到数据发生变更时,所有被观察者会被通知更新数据(即执行update方法)。
class Observer {
constructor (value) {
this.value = value
this.dep = new Dep()
// 重写所有属性的getter/setter
Object.keys(value).forEach(key => {
defineReactive(value, key)
})
}
}
// 将对象的属性转化为getter/setter的形式
export function defineReactive (obj, key, val) {
const dep = new Dep()
const property = Object.getOwnPropertyDescriptor(obj, key)
if (property && property.configurable === false) {
return
}
const getter = property && property.get
const setter = property && property.set
if ((!getter || setter) && arguments.length === 2) {
val = obj[key]
}
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: function reactiveGetter () {
const value = getter ? getter.call(obj) : val
if (window.target) {
dep.depend()
}
return value
},
set: function reactiveSetter (newVal) {
const value = getter ? getter.call(obj) : val
if (newVal === value) {
return
}
if (setter) {
setter.call(obj, newVal)
} else {
val = newVal
}
dep.notify()
}
})
}
示例说明
我们在Vue实例中,通常会将data对象中的属性转化为响应式的数据,以便Vue可以检测到数据变化,从而实现视图自动更新。我们使用以下示例来说明Dep和Observer的用法:
// 假设我们有以下初始数据
const data = {
name: 'John Smith',
age: 35
}
// 将初始数据转换为Observer对象,实现数据的响应式
const observer = new Observer(data)
// 添加一个Watch实例来监控数据的变化
const watcher = new Watcher(() => {
console.log('name changed:', data.name)
})
// 修改name属性的值
data.name = "Mary Johnson"
// 这时会触发watcher的update方法,在控制台输出: name changed: Mary Johnson
在这个示例中,我们通过将 data 对象转换为 Observer 对象来实现数据的响应式,然后创建Watcher对象来监控特定的数据变化,最后修改name属性的值时,watcher对象的update方法会被触发,从而在控制台输出新的值。
这样通过Dep和Observer的封装,我们可以很容易地实现 Vue 的响应式数据更新和视图重渲染。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Vue之Dep和Observer的用法及说明 - Python技术站