实现$wacth
const v = new Vue({
data:{
a:1,
b:2
}
})
v.$watch("a",()=>console.log("哈哈,$watch成功"))
setTimeout(()=>{
v.a = 5
},2000) //打印 哈哈,$watch成功
1.实现observer
export default class Observer{
constructor(value) {
this.value = value
this.walk(value)
}
//递归。。让每个字属性可以observe
walk(value){
Object.keys(value).forEach(key=>this.convert(key,value[key]))
}
convert(key, val){
defineReactive(this.value, key, val)
}
}
export function defineReactive (obj, key, val) {
var childOb = observe(val)
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: ()=>val,
set:newVal=> {
childOb = observe(newVal)//如果新赋值的值是个复杂类型。再递归它,加上set/get。。
}
})
}
export function observe (value, vm) {
if (!value || typeof value !== 'object') {
return
}
return new Observer(value)
}
代码很简单,就给每个属性(包括子属性)都加上get/set,
这样的话,这个对象的,有任何赋值,就会触发set方法。。
所以,我们是不是应该写一个消息-订阅器呢?这样的话,
一触发set方法,我们就发一个通知出来,然后,订阅这个消息的,就会怎样?。。。对咯。。收到消息。。。触发回调。
2.消息-订阅器
export default class Dep {
constructor() {
this.subs = []
}
addSub(sub){
this.subs.push(sub)
}
notify(){
this.subs.forEach(sub=>sub.update())
}
}
所以,每次set函数,调用的时候,我们是不是应该,触发notify,对吧。所以
我们把代码补充完整
export function defineReactive (obj, key, val) {
var dep = new Dep()
var childOb = observe(val)
Object.defineProperty(obj, key, {
enumerable: true,
configurable: true,
get: ()=>val,
set:newVal=> {
var value = val
if (newVal === value) {
return
}
val = newVal
childOb = observe(newVal)
dep.notify()
}
})
}
那么问题来了?谁是订阅者,对,是Watcher。。一旦 dep.notify()
就遍历订阅者,也就是Watcher,并调用他的update()方法
转载请注明: Vue教程中文网 - 打造国内领先的vue学习网站-vue视频,vue教程,vue学习,vue培训 » vue源码分析之实现observer和watcher(一)