【Vue2.0源码学习】生命周期篇-挂载阶段(mount)

news2024/12/27 5:26:03

文章目录

    • 1. 前言
    • 2. 挂载阶段分析
    • 3. 总结

1. 前言

模板编译阶段完成之后,接下来就进入了挂载阶段,从官方文档给出的生命周期流程图中可以看到,挂载阶段所做的主要工作是创建Vue实例并用其替换el选项对应的DOM元素,同时还要开启对模板中数据(状态)的监控,当数据(状态)发生变化时通知其依赖进行视图更新。

在这里插入图片描述

2. 挂载阶段分析

在上篇文章介绍模板编译阶段中我们说过,在完整版本的$mount方法中将模板编译完成之后,会回过头去调只包含运行时版本的$mount方法进入挂载阶段,所以要想分析挂载阶段我们必须从只包含运行时版本的$mount方法入手。

只包含运行时版本的$mount代码如下:

Vue.prototype.$mount = function (el,hydrating) {
  el = el && inBrowser ? query(el) : undefined;
  return mountComponent(this, el, hydrating)
};

可以看到,在该函数内部首先获取到el选项对应的DOM元素,然后调用mountComponent函数并将el选项对应的DOM元素传入,进入挂载阶段。那么,下面我们来看下mountComponent函数内部都干了些什么。

mountComponent函数的定义位于源码的src/core/instance/lifecycle.js中,如下:

export function mountComponent (vm,el,hydrating) {
    vm.$el = el
    if (!vm.$options.render) {
        vm.$options.render = createEmptyVNode
    }
    callHook(vm, 'beforeMount')

    let updateComponent

    updateComponent = () => {
        vm._update(vm._render(), hydrating)
    }
    new Watcher(vm, updateComponent, noop, {
        before () {
            if (vm._isMounted) {
                callHook(vm, 'beforeUpdate')
            }
        }
    }, true /* isRenderWatcher */)
    hydrating = false

    if (vm.$vnode == null) {
        vm._isMounted = true
        callHook(vm, 'mounted')
    }
    return vm
}

可以看到,在该函数中,首先会判断实例上是否存在渲染函数,如果不存在,则设置一个默认的渲染函数createEmptyVNode,该渲染函数会创建一个注释类型的VNode节点。如下:

vm.$el = el
if (!vm.$options.render) {
    vm.$options.render = createEmptyVNode
}

然后调用callHook函数来触发beforeMount生命周期钩子函数,如下:

callHook(vm, 'beforeMount')

该钩子函数触发后标志着正式开始执行挂载操作。

接下来定义了一个updateComponent函数,如下:

updateComponent = () => {
    vm._update(vm._render(), hydrating)
}

在该函数内部,首先执行渲染函数vm._render()得到一份最新的VNode节点树,然后执行vm._update()方法对最新的VNode节点树与上一次渲染的旧VNode节点树进行对比并更新DOM节点(即patch操作),完成一次渲染。

也就是说,如果调用了updateComponent函数,就会将最新的模板内容渲染到视图页面中,这样就完成了挂载操作的一半工作,即图中的上半部分:

在这里插入图片描述

为什么说是完成了一半操作呢?这是因为在挂载阶段不但要将模板渲染到视图中,同时还要开启对模板中数据(状态)的监控,当数据(状态)发生变化时通知其依赖进行视图更新。即图中的下半部分:

在这里插入图片描述

继续往下看,接下来创建了一个Watcher实例,并将定义好的updateComponent函数传入。要想开启对模板中数据(状态)的监控,这一段代码是关键,如下:

new Watcher(
    vm,                    // 第一个参数
    updateComponent,       // 第二个参数
    noop,                  // 第三个参数
    {                      // 第四个参数
        before () {
          if (vm._isMounted) {
            callHook(vm, 'beforeUpdate')
          }
        }
	},
    true                    // 第五个参数
)

可以看到,在创建Watcher实例的时候,传入的第二个参数是updateComponent函数。回顾一下我们在数据侦测篇文章中介绍Watcher类的时候,Watcher类构造函数的第二个参数支持两种类型:函数和数据路径(如a.b.c)。如果是数据路径,会根据路径去读取这个数据;如果是函数,会执行这个函数。一旦读取了数据或者执行了函数,就会触发数据或者函数内数据的getter方法,而在getter方法中会将watcher实例添加到该数据的依赖列表中,当该数据发生变化时就会通知依赖列表中所有的依赖,依赖接收到通知后就会调用第四个参数回调函数去更新视图。

换句话说,上面代码中把updateComponent函数作为第二个参数传给Watcher类从而创建了watcher实例,那么updateComponent函数中读取的所有数据都将被watcher所监控,这些数据中只要有任何一个发生了变化,那么watcher都将会得到通知,从而会去调用第四个参数回调函数去更新视图,如此反复,直到实例被销毁。

这样就完成了挂载阶段的另一半工作。

如此之后,挂载阶段才算是全部完成了,接下来调用挂载完成的生命周期钩子函数mounted

3. 总结

本篇文章介绍了生命周期中的第三个阶段——挂载阶段。

在该阶段中所做的主要工作是创建Vue实例并用其替换el选项对应的DOM元素,同时还要开启对模板中数据(状态)的监控,当数据(状态)发生变化时通知其依赖进行视图更新。

我们将挂载阶段所做的工作分成两部分进行了分析,第一部分是将模板渲染到视图上,第二部分是开启对模板中数据(状态)的监控。两部分工作都完成以后挂载阶段才算真正的完成了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1049054.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DIY手工坊商城小程序的作用有哪些

自己动手做的东西往往更具自豪感,也能锻炼自身的动手能力,而DIY手工坊无疑是小孩子、年轻人喜欢的地方,无论自己做还是成品都具备自由性、不受规格类型局限,比如手机壳、绘画、手工积木、雕塑等。 而对商家来说,经营收…

赋能工业数字化转型|辽宁七彩赛通受邀出席辽宁省工业互联网+安全可控先进制造业数字服务产业峰会

2023年9月25日下午,由软通动力信息技术(集团)股份有限公司主办的“工业互联网安全可控先进制造业数字服务产业峰会”在辽宁沈阳顺利举办。省市区各级政府、科研院所领导、技术专家、企业高管以及生态合作伙伴代表等齐聚一堂,共同探…

Konva事件机制

前言 不同于HTML或SVG标签可以直接绑定事件,Canvas是使用JavaScript来绘制内容,这意味着其内容没有具体的DOM,所以Canvas渲染引擎都会自己实现一套事件机制。Konva的事件机制支持图形的选中、拖拽等交互处理,同时还支持单个图形对…

微信小程序案例2-1:学生信息

文章目录 (二)准备图像素材(三)编写小程序页面结构 单击[确认] 清空页面结构文件index.wxml内容 修改页面配置文件index.json,不适用navigation-bar组件 删除全局配置文件app.json,删除渲染器配置&a…

一键开启默认打印机共享功能,如何用powershell编写一个一键开启windows本地默认打印机共享的脚本

环境: Win10 专业版 Win11专业版 powershell 问题描述: 一键开启默认打印机共享功能,如何用powershell编写一个一键开启windows本地默认打印机共享的脚本 解决方案: 修改Windows注册表来实现打印机共享:(未成功)打开注册表编辑器:按下Win + R组合键,输入"re…

手机,汽车大卖背后,华为生态进入发展新阶段

监制 | 何玺 排版 | 叶媛 从8月底至今,华为手机、汽车的热度就没有消退过。 如今的华为产品,从手机到AR眼镜,从智慧屏到汽车,几乎全线都处在一机难求、一车难求状态。 9月25日举行的华为秋季全场景新品发布会, 更是…

实验三十三、三端稳压器 LM7805 稳压性能的研究

一、题目 LM7805 输出电压、电压调整率、电流调整率以及输出纹波电压的研究。 二、仿真电路 电路如图1所示。集成稳压芯片采用 LM7805CT。 三、仿真内容 (1)测量图1(a)LM7805CT 的电压调整率,测量条件为 I O 50…

【数据结构与算法】通过双向链表和HashMap实现LRU缓存 详解

这个双向链表采用的是有伪头节点和伪尾节点的 与上一篇文章中单链表的实现不同,区别于在实例化这个链表时就初始化了的伪头节点和伪尾节点,并相互指向,在第一次添加节点时,不需要再考虑空指针指向问题了。 /*** 通过链表与HashMa…

算法与数据结构-Trie树

文章目录 什么是“Trie 树”?如何实现一棵 Trie 树?Trie 树真的很耗内存吗?Trie 树与散列表、红黑树的比较 什么是“Trie 树”? Trie 树,也叫“字典树”。顾名思义,它是一个树形结构。它是一种专门处理字符…

SolidWorks 入门笔记03:生成工程图和一键标注

默认情况下,SOLIDWORKS系统在工程图和零件或装配体三维模型之间提供全相关的功能,全相关意味着无论什么时候修改零件或装配体的三维模型,所有相关的工程视图将自动更新,以反映零件或装配体的形状和尺寸变化;反之&#…

软考高级之系统架构师之计算机基础

概述 今天是9月28日,距离软考高级只剩37天,加油! 概念 三种周期: Clock Cycle:时钟周期,CPU主频,又称为时钟频率,时钟周期是时钟频率的倒数Instruction Cycle:指令周…

人工智能 与 搜索引擎的较量

随着科技的不断进步,人工智能(AI)已经渗透到了我们生活的方方面面,搜索引擎也不例外。AI与传统搜索引擎之间的较量成为了科技界和互联网用户关注的热点话题。 人工智能 与 搜索引擎的较量 A - 搜索引擎B - 人工智能AI 的优势理解力…

感谢信 | 企企通赋能鲜丰水果搭建特色数字化供应链协同系统,领跑中国水果连锁品牌

近日,由企企通携手鲜丰水果股份有限公司(以下简称“鲜丰水果”)打造的一站式数字化采购供应链管理平台成功上线。 鲜丰水果项目顺利上线后,客户对企企通项目团队的努力付出作出了高度评价,并收到了来自鲜丰水果的感谢信…

Java中String转换为double类型

这次的java作业是写一个数字转换的小项目,其中从输入框中获取的是String类型,但是要进行数字操作,此时要用到很多操作String类型数据的方法了。 从javafx输入框中获取到String类型后,首先是要判断是否能转换为数字或者小数形式&a…

多线程 dispatch

51423 https://blog.csdn.net/yanhaijunyan/article/details/115083522

问题 - 谷歌浏览器 network 看不到接口请求解决方案

谷歌浏览器 -> 设置 -> 重置设置 -> 将设置还原为其默认值 查看接口情况,选择 All 或 Fetch/XHR,勾选 Has blocked cookies 即可 如果万一还不行,卸载浏览器重装。 参考:https://www.cnblogs.com/tully/p/16479528.html

WebGL 渲染三维图形作为纹理贴到另一个三维物体表面

目录 渲染到纹理 帧缓冲区对象和渲染缓冲区对象 帧缓冲区对象 帧缓冲区对象的结构 如何实现渲染到纹理 示例程序(FramebufferObject.js) 创建帧缓冲区对象(gl.createFramebuffer()) gl.createFra…

windows:批处理bat入门

文章目录 什么是BAT常用命令与语法help与/?titlecolormodeechopausecallremset/a/p gotostartifif errorlevel for普通用法for /l 用法for /d用法for /r用法for /f用法in (file)delims和tokensskipeolusebackq 变量扩展变量延迟 setlocalshiftdirrd(删除文件夹&…

云中网络的隔离GREVXLAN

底层的物理网络设备组成的网络我们称为 Underlay 网络,而用于虚拟机和云中的这些技术组成的网络称为 Overlay 网络,这是一种基于物理网络的虚拟化网络实现。 第一个技术是 GRE,全称 Generic Routing Encapsulation,它是一种 IP-o…

Xposed 替换Textview文案

Xposed 替换Textview文案 这篇主要写下替换Textview的文案,主要实现比如脱敏。 public class TextViewHook {private static final String TAG "TextViewHook";public static void hook(XC_LoadPackage.LoadPackageParam lpparam) {Log.i(TAG, "ho…