摘要:写文章不容易,点个赞呗兄弟专注源码分享,文章分为白话版和源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于版本如果你觉得排版难看,请点击下面链接或者拉到下面关注公众号也可以吧原理依赖更新源码版如果对依赖收集完
写文章不容易,点个赞呗兄弟
专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧
研究基于 Vue版本 【2.5.17】
如果你觉得排版难看,请点击 下面链接 或者 拉到 下面关注公众号也可以吧
【Vue原理】依赖更新 - 源码版
如果对依赖收集完全没有概念的同学,可以先看我这篇白话版
响应式原理 - 白话版
我们已经讲过了 依赖收集
【Vue原理】依赖收集 - 源码版之基本数据类型
【Vue原理】依赖收集 - 源码版之引用数据类型
现在就要看依赖更新了哈哈哈,毕竟收集完是要更新的嘛
其实依赖更新挺简单的,就是两步
修改属性值
通知保存的依赖进行更新
重点只需要看 Object.defineProperty 设置的set 函数,当给数据重赋新值的时候,自然会触发 set 函数,完成依赖更新
function defineReactive(obj, key, val) { var dep = new Dep(); var childOb = observe(val); Object.defineProperty(obj, key, { get(){ ... 属性被读取,完成依赖收集 // 返回闭包值 return val }, set(newVal) { // 值没有变化 if (newVal ===val) return // 修改闭包值 val = newVal; // 如果属性已经存在过,设置新值的时候,会重新调用一遍 childOb = observe(newVal); // 触发更新 dep.notify(); } }); }
依赖更新重点就重在 通知更新
而通知更新的重点,只有一句话,【dep.notify】
所以,我们重点去了解这句话,如何通知,如何更新
好的, dep 在第一篇讲过了
【Vue原理】依赖收集 - 源码版之基本数据类型
我们知道,dep 主要是存储依赖的,再看一遍源码
var Dep = function Dep() { this.subs = []; // 依赖存储器 }; // 遍历 subs ,逐个通知依赖,就是逐个调用 watcher.update Dep.prototype.notify = function() { var subs = this.subs.slice(); for (var i = 0, l = subs.length; i < l; i++) { subs[i].update(); } };
看过了源码,我们知道了,原来通知更新是【遍历依赖存储器】,然后一个个【调用 watcher.update】
因为 subs 装的是 watcher,所以,subs[0].update 就是 watcher.update
于是问题又来了,watcher.update 是怎么就更新了???
function Watcher(vm, expOrFn) { this.vm = vm; // 保存传入的更新函数 this.getter = expOrFn; // 新建 watcher 的时候,立即执行更新函数 this.get(); }; Watcher.prototype.get = function() { // 执行更新函数 this.getter.call(this.vm,this.vm); }; Watcher.prototype.update = function() { this.get() }
看到上面的源码
1Watcher 新建实例的时候,会保存传入的函数(这个函数会作为更新用)
2watcher 实例有 update 方法,作用是执行上一步保存的更新函数
那么 watcher 是什么时候开始创建的呢?
以页面 watcher 举例,探索整个实例构建的基本流程
function Vue(options) { this._init(options); } Vue.prototype._init = function(options) { // ...处理组件选项等 this.$mount() } Vue.prototype.$mount = function() { // ...解析template成redner函数保存 /** 每个实例新建一个watcher, 并且利用watcher 保存更新函数 **/ new Watcher(this, // 这个函数是更新函数,传入watcher保存下来,用于后面页面初始化或者页面更新 function() { /** ...调用保存的渲染函数生成VNode, 并生成DOM插入页面中**/ } ); };
看上面的源码 和注释大概就可以很清楚了
从 【new Vue】 到 【vm._init】 初始化 到 【vm.$mount】 挂载到页面,整个流程就完整了
重点是清楚 watcher的更新函数
更新函数
我们可以看到这个页面的更新函数,作用是调用 渲染函数,然后生成DOM节点插入页面中。
更新函数会传入Watcher ,然后被保存到 watcher 的实例中
“整个函数涉及的源码很多,但是这里一律而过”
所以,通知更新做了这些工作
1、直接调用 watcher.update,也就是重新调用给 watcher 保存的更新函数
2、更新更新函数就是执行渲染函数,然后读取实例最新的值(已被修改过的值),最后重新生成DOM 节点
3、DOM 节点 插入或替换页面,完成更新
画个通知流程图
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/105383.html
摘要:所以我今后打算把每一个内容分成白话版和源码版。有什么错误的地方,感谢大家能够指出响应式系统我们都知道,只要在实例中声明过的数据,那么这个数据就是响应式的。什么是响应式,也即是说,数据发生改变的时候,视图会重新渲染,匹配更新为最新的值。 写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 V...
摘要:当东西发售时,就会打你的电话通知你,让你来领取完成更新。其中涉及的几个步骤,按上面的例子来转化一下你买东西,就是你要使用数据你把电话给老板,电话就是你的,用于通知老板记下电话在电话本,就是把保存在中。剩下的步骤属于依赖更新 写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【...
写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版难看,请点击 下面链接 或者 拉到 下面关注公众号也可以吧 【Vue原理】Props - 源码版 今天记录 Props 源码流程,哎,这东西,就算是研究过了,也真是会随着时间慢慢忘记的。 幸好我做...
写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版难看,请点击 下面链接 或者 拉到 下面关注公众号也可以吧 【Vue原理】NextTick - 源码版 之 服务Vue 初次看的兄弟可以先看 【Vue原理】NextTick - 白话版 简单了解下...
摘要:写文章不容易,点个赞呗兄弟专注源码分享,文章分为白话版和源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于版本如果你觉得排版难看,请点击下面链接或者拉到下面关注公众号也可以吧原理依赖收集源码版之引用数据类型上 写文章不容易,点个赞呗兄弟专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于...
阅读 1246·2021-09-23 11:51
阅读 1247·2021-09-04 16:45
阅读 599·2019-08-30 15:54
阅读 2056·2019-08-30 15:52
阅读 1572·2019-08-30 11:17
阅读 3077·2019-08-29 13:59
阅读 1988·2019-08-28 18:09
阅读 361·2019-08-26 12:15