vue如何实现observer和watcher源码解析
本文能帮你做什么?好奇vue双向绑定的同学,可以部分缓解好奇心,还可以帮你了解如何实现$watch。 前情回顾我之前写了一篇没什么干货的文章,并且刨了一个大坑。 今天,打算来填一天,并再刨一个。 不过话说说回来了,看本文之前,如果不知道Object.defineProperty,还必须看看解析神奇的 不得不感慨vue的作者,人长得帅,码写的也好,本文是根据作者源码,摘取出来的 本文将实现什么正如上一篇许下的承诺一样,本文要实现一个$wacth console.log("哈哈,$watch成功"))
setTimeout(()=>{
v.a = 5
},2000) //打印 哈哈,$watch成功
为了帮助大家理清思路。。我们就做最简单的实现。。只考虑对象不考虑数组 1. 实现 observer思路:我们知道的特性了,我们就利用它的set和get。我们将要observe的对象,通过递归,将它所有的属性,包括子属性的属性,都给加上set和get。这样的话,给这个对象的某个属性赋值,就会触发set。开始吧 this.convert(key,value[key]))
}
convert(key,val){
defineReactive(this.value,key,val)
}
}
export function defineReactive (obj,val) { export function observe (value,vm) { 代码很简单,就给每个属性(包括子属性)都加上get/set,这样的话,这个对象的,有任何赋值,就会触发set方法。。 所以,我们是不是应该写一个消息-订阅器呢? 这样的话,一触发set方法,我们就发一个通知出来,然后,订阅这个消息的,就会怎样?对咯。、收到消息、触发回调。 2. 消息-订阅器很简单,我们维护一个数组,,这个数组,就放订阅着,一旦触发notify,订阅者就调用自己的update方法 sub.update())
}
}
所以,每次set函数,调用的时候,我们是不是应该,触发notify,对吧。所以我们把代码补充完整 {
var value = val
if (newVal === value) {
return
}
val = newVal
childOb = observe(newVal)
dep.notify()
}
})
}
那么问题来了。谁是订阅者。对,是Watcher。一旦 dep.notify()就遍历订阅者,也就是Watcher,并调用他的update()方法 3. 实现一个Watcher我们想象这个Watcher,应该用什么东西。update方法,嗯这个毋庸置疑,还有呢。console.log("哈哈,$watch成功")) 对表达式(就是那个“a”) 和 回调函数,这是最基本的,所以我们简单写写 那么问题来了,我们怎样将通过样判断他是Watcher的this.get调用的,而不是我们普通调用的呢。 对,在Dep定义一个全局唯一的变量,跟着思路我们写一下 这样的话,我们只需要在Object.defineProperty的get要调用的函数里,判断有没有值,就知道到底是Watcher 在get,还是我们自己在查看赋值,如果是Watcher的话就addSub(),代码补充一下 Object.defineProperty(obj,get: ()=>{
// 说明这是watch 引起的 if(Dep.target){ dep.addSub(Dep.target) } return val },set:newVal=> { var value = val if (newVal === value) { return } val = newVal childOb = observe(newVal) dep.notify() } }) } 最后不要忘记,在Dep.js中加上这么一句
还差一步就大功告成了,我们要把以上代码配合Vue的$watch方法来用,要watch Vue实例的属性,算了,不要理会我在说什么,直接看代码吧 <div class="jb51code"> export default class Vue { $watch(expOrFn,cb,options){ _proxy(key) { 非常简单。两件事,observe自己的data,代理自己的data,使访问自己的属性,就是访问子data的属性。。 截止到现在,在我们只考虑最简单情况下,整个流程终于跑通了。肯定会有很多bug,本文主要目的是展示整个工作流,帮助读者理解。 代码在..., 我是一万个不想展示自己代码,因为很多槽点,还请见谅 下一篇,有两个方向,将聊一聊如何实现双向绑定,或者是如何watch数组。 关于vue2.0的新文章 本文已被整理到了《》,欢迎大家学习阅读。 关于vue.js组件的教程,请大家点击专题进行学习。 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程之家。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |