文档章节

【Vue原理】依赖更新 - 源码版

神仙朱
 神仙朱
发布于 07/06 16:56
字数 1125
阅读 12
收藏 1

写文章不容易,点个赞呗兄弟 专注 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 节点 插入或替换页面,完成更新

画个通知流程图

公众号

公众号

© 著作权归作者所有

神仙朱
粉丝 6
博文 55
码字总数 93306
作品 0
深圳
程序员
私信 提问
【Vue原理】Props - 源码版

写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版...

神仙朱
07/06
41
0
【Vue原理】依赖收集 - 源码版之基本数据类型

写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版...

神仙朱
07/05
0
0
【Vue原理】NextTick - 源码版 之 服务Vue

写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版...

神仙朱
07/15
4
0
【Vue原理】Computed - 源码版

写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版...

神仙朱
07/06
25
0
【Vue原理】依赖收集 - 源码版之引用数据类型

写文章不容易,点个赞呗兄弟 专注 Vue 源码分享,文章分为白话版和 源码版,白话版助于理解工作原理,源码版助于了解内部详情,让我们一起学习吧研究基于 Vue版本 【2.5.17】 如果你觉得排版...

神仙朱
07/05
11
0

没有更多内容

加载失败,请刷新页面

加载更多

计算机实现原理专题--二进制减法器(二)

在计算机实现原理专题--二进制减法器(一)中说明了基本原理,现准备说明如何来实现。 首先第一步255-b运算相当于对b进行按位取反,因此可将8个非门组成如下图的形式: 由于每次做减法时,我...

FAT_mt
今天
5
0
好程序员大数据学习路线分享函数+map映射+元祖

好程序员大数据学习路线分享函数+map映射+元祖,大数据各个平台上的语言实现 hadoop 由java实现,2003年至今,三大块:数据处理,数据存储,数据计算 存储: hbase --> 数据成表 处理: hive --> 数...

好程序员官方
今天
7
0
tabel 中含有复选框的列 数据理解

1、el-ui中实现某一列为复选框 实现多选非常简单: 手动添加一个el-table-column,设type属性为selction即可; 2、@selection-change事件:选项发生勾选状态变化时触发该事件 <el-table @sel...

everthing
今天
6
0
【技术分享】TestFlight测试的流程文档

上架基本需求资料 1、苹果开发者账号(如还没账号先申请-苹果开发者账号申请教程) 2、开发好的APP 通过本篇教程,可以学习到ios证书申请和打包ipa上传到appstoreconnect.apple.com进行TestF...

qtb999
今天
10
0
再见 Spring Boot 1.X,Spring Boot 2.X 走向舞台中心

2019年8月6日,Spring 官方在其博客宣布,Spring Boot 1.x 停止维护,Spring Boot 1.x 生命周期正式结束。 其实早在2018年7月30号,Spring 官方就已经在博客进行过预告,Spring Boot 1.X 将维...

Java技术剑
今天
18
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部