摘要:依赖收集是在响应式基础上进行的,不熟悉的同学可以先了解响应式原理。定义一个依赖收集类。订阅者,当依赖收集的时候回到中,在修改中数据的时候会触发的,从而回调渲染函数。
写在前面
因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出。
文章的原地址:https://github.com/answershuto/learnVue。
在学习过程中,为Vue加上了中文的注释https://github.com/answershuto/learnVue/tree/master/vue-src,希望可以对其他想学习Vue源码的小伙伴有所帮助。
可能会有理解存在偏差的地方,欢迎提issue指出,共同学习,共同进步。
依赖收集是在响应式基础上进行的,不熟悉的同学可以先了解《响应式原理》。
为什么要依赖收集先看下面这段代码
new Vue({ template: `text1: {{text1}} text2: {{text2}}`, data: { text1: "text1", text2: "text2", text3: "text3" } });按照之前《响应式原理》中的方法进行绑定则会出现一个问题——text3在实际模板中并没有被用到,然而当text3的数据被修改的时候(this.text3 = "test")的时候,同样会触发text3的setter导致重新执行渲染,这显然不正确。
先说说Dep当对data上的对象进行修改值的时候会触发它的setter,那么取值的时候自然就会触发getter事件,所以我们只要在最开始进行一次render,那么所有被渲染所依赖的data中的数据就会被getter收集到Dep的subs中去。在对data中的数据进行修改的时候setter只会触发Dep的subs的函数。
定义一个依赖收集类Dep。
class Dep () { constructor () { this.subs = []; } addSub (sub: Watcher) { this.subs.push(sub) } removeSub (sub: Watcher) { remove(this.subs, sub) } notify () { // stabilize the subscriber list first const subs = this.subs.slice() for (let i = 0, l = subs.length; i < l; i++) { subs[i].update() } } }Watcher订阅者,当依赖收集的时候回addSub到sub中,在修改data中数据的时候会触发Watcher的notify,从而回调渲染函数。
class Watcher () { constructor (vm, expOrFn, cb, options) { this.cb = cb; this.vm = vm; /*在这里将观察者本身赋值给全局的target,只有被target标记过的才会进行依赖收集*/ Dep.target = this; /*触发渲染操作进行依赖收集*/ this.cb.call(this.vm); } update () { this.cb.call(this.vm); } }开始依赖收集class Vue { constructor(options) { this._data = options.data; observer(this._data, options.render); let watcher = new Watcher(this, ); } } function defineReactive (obj, key, val, cb) { /*在闭包内存储一个Dep对象*/ const dep = new Dep(); Object.defineProperty(obj, key, { enumerable: true, configurable: true, get: ()=>{ if (Dep.target) { /*Watcher对象存在全局的Dep.target中*/ dep.addSub(Dep.target); } }, set:newVal=> { /*只有之前addSub中的函数才会触发*/ dep.notify(); } }) } Dep.target = null;将观察者Watcher实例赋值给全局的Dep.target,然后触发render操作只有被Dep.target标记过的才会进行依赖收集。有Dep.target的对象会讲Watcher的实例push到subs中,在对象被修改出发setter操作的时候dep会调用subs中的Watcher实例的update方法进行渲染。
关于作者:染陌
Email:answershuto@gmail.com or answershuto@126.com
Github: https://github.com/answershuto
Blog:http://answershuto.github.io/
知乎专栏:https://zhuanlan.zhihu.com/ranmo
掘金: https://juejin.im/user/58f87ae844d9040069ca7507
osChina:https://my.oschina.net/u/3161824/blog
转载请注明出处,谢谢。
欢迎关注我的公众号
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/84987.html
相关文章
深入浅出Vue响应式原理
摘要:总结最后我们依照下图参考深入浅出,再来回顾下整个过程在后,会调用函数进行初始化,也就是过程,在这个过程通过转换成了的形式,来对数据追踪变化,当被设置的对象被读取的时候会执行函数,而在当被赋值的时候会执行函数。 前言 Vue 最独特的特性之一,是其非侵入性的响应式系统。数据模型仅仅是普通的 JavaScript 对象。而当你修改它们时,视图会进行更新。这使得状态管理非常简单直接,不过理解...
vue.js源码 - 剖析observer,dep,watch三者关系 如何具体的实现数据双向绑定
摘要:双向数据绑定的核心和基础是其内部真正参与数据双向绑定流程的主要有和基于和发布者订阅者模式,最终实现数据的双向绑定。在这里把双向数据绑定分为两个流程收集依赖流程依赖收集会经过以上流程,最终数组中存放列表,数组中存放列表。 Vue双向数据绑定的核心和基础api是Object.defineProperty,其内部真正参与数据双向绑定流程的主要有Obderver、Dep和Watcher,基于d...
从Vue.js源码角度再看数据绑定
摘要:在学习过程中,为加上了中文的注释,希望可以对其他想学习源码的小伙伴有所帮助。数据绑定原理前面已经讲过数据绑定的原理了,现在从源码来看一下数据绑定在中是如何实现的。 写在前面 因为对Vue.js很感兴趣,而且平时工作的技术栈也是Vue.js,这几个月花了些时间研究学习了一下Vue.js源码,并做了总结与输出。文章的原地址:https://github.com/answershuto/le...
Vue源码解析(2)-vue双向数据绑定原理
摘要:与状态同步非常困难通过添加观察者监测变化,如和。应用中状态的属性会被监测,当它们发生变化时,只有依赖了发生变化属性的元素会被重新渲染。 现代 js 框架存在的根本原因 然而通常人们(自以为)使用框架是因为:它们支持组件化;它们有强大的社区支持;它们有很多(基于框架的)第三方库来解决问题;它们有很多(很好的)第三方组件;它们有浏览器扩展工具来帮助调试;它们适合做单页应用。 Keeping...
发表评论
0条评论
阅读 2183·2021-09-22 15:25
阅读 3584·2019-08-30 12:48
阅读 2146·2019-08-30 11:25
阅读 2300·2019-08-30 11:05
阅读 695·2019-08-29 17:28
阅读 3250·2019-08-26 12:16
阅读 2568·2019-08-26 11:31
阅读 1605·2019-08-23 17:08