Vue工作机制------发布和订阅者模式(Watcher)
2022-07-03 09:33阅读:
依赖收集与追踪 ,看下面的例子 new Vue({
template: `
<</span>div>
<</span>span>{{name1}}</</span>span>
<</span>span>{{name2}}</</span>span>
<</span>span>{{name1}}</</span>span>
</</span>div>
`,
data: {
name1: '手冢国光',
name2: '不二周助',
name3: '越前龙马'
},
created(){
this.name1 = '问题不断'
this.name3 = '小鑫'
}
})
name1 改变时,视图更新
name2 改变时,视图更新
name3 没有用到不用更新
在程序开始之前,对模板进行一次遍历,找出和数据有依赖的部分,收集保存下来,在需要更新的时候调用,这就是依赖收集的目的
再定义 两个类,依赖对象和观察者
class MVue {
// 接收配置对象
constructor(options) {
// 缓存options
this.$options =
options
// 数据响应化
this.$data =
options.data
// 监听函数
this.observe(this.$data)
// 模拟watcher创建
new Watcher()
this.$data.test
new Watcher()
this.$data.foo.user
}
// 监听函数
observe(val) {
if(!val || typeof
val !== 'object'){
return
}
// 遍历该对象
Object.keys(val).forEach(key
=> {
// 定义响应式,对每一个key(属性)进行定义
this.defineReactive(val,key,
val[key])
})
}
// 数据响应化
defineReactive(obj,key,
value) {
this.observe(value) //
递归解决数据嵌套
//初始化dep
const dep = new
Dep()
Object.defineProperty(obj,key,{
get(){
Dep.target &&
dep.addDep(Dep.target)
return value
},
set(newVal){
// 如果新值和老值相同
if(newVal === value){
return
}
value = newVal
// console.log(`${key}属性更新了:${value}`)
dep.notify()
}
})
}
}
// Dep(依赖对象): 用来管理Watcher
class Dep {
constructor() {
// 这里存放若干个依赖(watcher) (一个watcher对应一个属性)
this.deps = []
}
// 添加依赖方法
addDep(dep) {
this.deps.push(dep)
}
// 通知所有的watcher
notify(){
// 通知所有依赖去做更新
this.deps.forEach(dep
=> dep.update())
}
}
// Watcher 观察者
class Watcher {
constructor() {
// 将当前的watcher实例指定到Dep静态属性target
Dep.target = this
}
update() {
console.log('属性更新了')
}
}
增加一个Dep类的对象,用来收集Watcher对象,读数据的时候,会触发getter函数把当前的Watcher对象(存在Dep.target中)收集到Dep类中
写数据时,会触发setter方法,通知Dep类调用notify来触发所有watcher对象的update方法更新对应视图