vue源码分析(十)—— 生命周期

文章目录

  • 前言
  • 一、关键方法 callHook
  • 二、详细的钩子函数说明
    • 1.beforeCreate和create
    • 2.beforeMount & mounted
      • 注意点
      • 组件(非根组件)的渲染节点
        • (1)invokeInsertHook函数
        • (2)insert方法
        • (3)insert方法说明
    • 3.beforeUpdate & updated
      • (1)beforeUpdate 的执行时机是在渲染 Watcher 的 before 函数中
      • (2)update 的执行时机在flushSchedulerQueue 函数调用
      • (3)问题:为什么在 callUpdatedHooks 函数中,只有 vm._watcher 的回调执行完毕后,才会执行 updated 钩子函数
    • 4.beforeDestroy & destroyed
  • 总结


前言

生命周期就不过多说明了。主要是讲背的八股文通过源码来解释,为什么不同的钩子函数有不同的效果
附上生命周期的流程图,如下或点击官网查看:vue2官网生命周期流程图
在这里插入图片描述


一、关键方法 callHook

方法路径:src\core\instance\lifecycle.ts

在这里插入图片描述

二、详细的钩子函数说明

1.beforeCreate和create

路径: src\core\instance\init.ts

beforeCreate和create 初始化前后,其实是在初始化函数中执行初始化数据的前后,也就是data method computed watch等属性。

在这里插入图片描述

2.beforeMount & mounted

路径: src\core\instance\init.ts

beforeMount & mounted 挂载前后,挂载前后其实就是生成了所有的虚拟DOM。
(挂载的含义:描述dom的数据需要整理,其实就是一堆(虚拟dom)对象储存了一堆数据,然后这些数据用js的API,比如createElement,创造出dom,这个过程是挂载前的动作。 创造出的dom还没有被使用,仅仅在内存中,需要“挂载”,然后你最外层一个叫app的id的dom,挂载就是document.querySelector(‘app’).appendChild(dom),就完成挂载啦。

在这里插入图片描述

注意点

(1)这里对 mounted 钩子函数执行有一个判断逻辑,vm.$vnode 如果为 null,则表明这不是一次组件的初始化过程,也就是根组件的渲染通过外部 new Vue 初始化过程。那么对于组件(非根组件)的 mounted 时机在哪里?

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

组件(非根组件)的渲染节点

(1)invokeInsertHook函数

组件的 VNode patch 到 DOM 后,会执行 invokeInsertHook 函数,把 insertedVnodeQueue 里保存的钩子函数依次执行一遍,它的定义在 src/core/vdom/patch.js 中:
在这里插入图片描述

(2)insert方法

在这里插入图片描述

(3)insert方法说明

我们可以看到,insert方法中每个子组件都是在这个钩子函数中执行 mounted 钩子函数,并且我们之前分析过,insertedVnodeQueue 的添加顺序是先子后父,所以对于同步渲染的子组件而言,mounted 钩子函数的执行顺序也是先子后父。

3.beforeUpdate & updated

beforeUpdate & updated 更新前后,顾名思义,就是在数据变化前后执行的钩子函数

(1)beforeUpdate 的执行时机是在渲染 Watcher 的 before 函数中

路径:src\core\instance\lifecycle.ts
在这里插入图片描述

(2)update 的执行时机在flushSchedulerQueue 函数调用

路径: src\core\observer\scheduler.ts
在这里插入图片描述

(3)问题:为什么在 callUpdatedHooks 函数中,只有 vm._watcher 的回调执行完毕后,才会执行 updated 钩子函数

在组件 mount 的过程中,会实例化一个渲染的 Watcher 去监听 vm 上的数据变化重新渲染,这段逻辑发生在 mountComponent 函数执行的时候:
路径:src\core\instance\lifecycle.ts
在这里插入图片描述
在实例化 Watcher 的过程中,它的构造函数里会判断 isRenderWatcher,接着把当前 watcher 的实例赋值给 vm._watcher
路径: src\core\observer\watcher.ts
在这里插入图片描述
把当前 wathcer 实例 push 到 vm._watchers 中,vm._watcher 是专门用来监听 vm 上数据变化然后重新渲染的,所以它是一个渲染相关的 watcher,因此在 callUpdatedHooks 函数中,只有 vm._watcher 的回调执行完毕后,才会执行 updated 钩子函数。

4.beforeDestroy & destroyed

beforeDestroy & destroyed销毁 前后,就是$destroy方法中

路径:src\core\instance\lifecycle.ts
在这里插入图片描述

beforeDestroy 钩子函数的执行时机是在 $destroy 函数执行最开始的地方,接着执行了一系列的销毁动作,包括从 parent 的 $children 中删掉自身,删除 watcher,当前渲染的 VNode 执行销毁钩子函数等,执行完毕后再调用 destroy 钩子函数。

注意点:在 $destroy 的执行过程中,它又会递归调用 vm.patch(vm._vnode, null) 触发它子组件的销毁钩子函数,所以 destroy 钩子函数执行顺序是先子后父,和 mounted 过程一样。


总结

遇到过的面试题

问:create和mounted的区别?
答:create是初始化后执行的函数,mounted是挂载后执行的函数。
问:那我如何在create执行dom操作呢?
答:在create中使用setTimeout或nextTick即可

问:父子组件中的钩子函数如何执行
答:

加载渲染过程: 父beforeCreate->父created->父beforeMount->子beforeCreate->子created->子beforeMount->子mounted->父mounted

子组件更新过程
父beforeUpdate->子beforeUpdate->子updated->父updated

父组件更新过程
父beforeUpdate->父updated

销毁过程
父beforeDestroy->子beforeDestroy->子destroyed->父destroyed

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【运维】部署MKDocs

部署MKDocs obsidian 记录笔记,通过 mkdocs 私有化部署。 1 使用MKDocs创建笔记 创建仓库,安装 Material for MkDocs 和 mkdocs-minify-plugin mkdir tmp cd tmp git initpip install mkdocs-material pip install mkdocs-minify-pluginmkdocs new .2 …

深度学习——神经网络中前向传播、反向传播与梯度计算原理

一、前向传播 1.1 概念 神经网络的前向传播(Forward Propagation)就像是一个数据处理的流水线。从输入层开始,按照网络的层次结构,每一层的神经元接收上一层神经元的输出作为自己的输入,经过线性变换(加权…

面试突击-JAVA集合类(持续更新...)

前言 这篇文档非常适合面试突击人群,java集合类是面试高频问点,阅读完此文章可以直接应对面试官一切问题,最终吊打面试官。 概览 Java 集合,也叫作容器,主要是由两大接口派生而来:一个是 Collection接口&am…

Ps:创建数据驱动的图形 - 数据组

在 Photoshop 的“变量” Variables对话框中,可以为某一图层定义(或关联)变量并指定变量类型和变量值。 请参阅: 《Ps:创建数据驱动的图形 - 定义变量》 每个实例的变量值的集合构成一个数据组 Data Set。在相应的数据…

小猫可以吃面包吗?

在宠物饲养日益普及的当下,小猫的饮食健康成为众多铲屎官关注的焦点。其中,小猫是否可以吃面包这一问题引发了不少讨论。 从面包的成分来看,其主要原料是面粉、水、酵母和盐,部分还会添加糖、油脂、鸡蛋、牛奶等。面粉富含碳水化…

OSI七层模型和交换机

概念讲解 OSI(Open System Interconnection,开放系统互连)七层模型是一种网络通信的参考模型,它将网络通信的功能分为七个层次,每个层次负责特定的任务。 七层模型记忆口诀:物(物理层&#xf…

算法题(19):多数元素

审题: 数组不为空且一定存在众数。需要返回众数的数值 思路: 方法一:哈希映射 先用哈希映射去存储对应数据出现的次数,然后遍历找到众数并输出 当然也可以在第一次映射的过程中就维护一个出现次数最多的数据,这样子就可…

【Chrome】浏览器提示警告Chrome is moving towards a new experience

文章目录 前言一、如何去掉 前言 Chrome is moving towards a new experience that allows users to choose to browse without third-party cookies. 这是谷歌浏览器(Chrome)关于隐私策略更新相关的提示 提示:以下是本篇文章正文内容&…

低代码开源项目Joget的研究——基本概念和Joget7社区版应用

大纲 1. 基本概念1.1 Form1.1.1 Form1.1.1.1 概述1.1.1.2 主要特点和用途1.1.1.3 创建和使用 Form1.1.1.4 示例 1.1.2 Section1.1.2.1 概述1.1.2.2 主要特点和用途1.1.2.3 示例 1.1.3 Column1.1.4 Field1.1.5 示例 1.2 Datalist1.2.1 Datalist1.2.1.1 主要特点和用途1.2.1.2 创…

安装winserver2008R2虚拟机步骤

一、服务器系统介绍 1.1什么是服务器? 服务器英文名称为“Server”,指的是网络环境下为客户机(Client)提供某种服务的专用计算机,服务器安装有网络操作系统(如Windows 2000 Server、Linux、Unix等)和各种服务器应用系统软件(如Web服务、电子…

在开发嵌入式系统时,尤其是处理大数时,会遇到取值范围的问题。51单片机通常没有内建大整数支持,因此我们需要采用不同的方法来解决这一问题

00 两种可行方法分别是: 使用数组存储每一位数据并进行进位运算:通过将大数按位拆分成数组,然后实现逐位加法、进位等操作。使用符号变量进行计算:将数值分成低位和高位,分别用符号变量进行计算。 01:使用…

uniapp通过v-if进行判断时,会出现闪屏?【已解决】

1.问题:按钮切换时,通过v-if来判断,会出现闪烁情况,影响用户体验 2.v-if 闪烁问题可能的原因 ‌条件切换频繁‌:如果 v-if 指令的条件在短时间内频繁切换,会导致元素不断被销毁和重新创建,从而…

FME教程:一键批量调换图斑X、Y坐标,解决因为坐标弄反了,导致GIS弹窗提示“范围不一致”警告问题

目录 一、实现效果 二、实现过程 1.读取数据 2.提取坐标 3.调换图斑的X、Y坐标 4.输出成果 5.模板的使用 三、总结 在工作中有时候会出现因为失误导致图斑的X、Y坐标弄反,在GIS中打开是会提示“范围不一致”警告的弹窗警告,如果重做工作量非常大…

MySQL数据库——索引结构之B+树

本文先介绍数据结构中树的演化过程,之后介绍为什么MySQL数据库选择了B树作为索引结构。 文章目录 树的演化为什么其他树结构不行?为什么不使用二叉查找树(BST)?为什么不使用平衡二叉树(AVL树)&a…

探索贝叶斯魔法和误差的秘密

引言 今天我们要一起学习两个神秘的魔法概念:贝叶斯魔法和误差的秘密。这些概念听起来可能有点复杂,但别担心,我会用最简单的方式来解释它们。 一、贝叶斯魔法 贝叶斯魔法是一种预测的魔法,它帮助我们理解在不确定的情况下事情…

FFmpeg:详细安装教程与环境配置指南

FFmpeg 部署完整教程 在本篇博客中,我们将详细介绍如何下载并安装 FFmpeg,并将其添加到系统的环境变量中,以便在终端或命令行工具中直接调用。无论你是新手还是有一定基础的用户,这篇教程都能帮助你轻松完成 FFmpeg 的部署。 一、…

BGP特性实验

实验拓扑 实验需求及解法 本实验模拟大规模BGP网络部署,使用4字节AS号,传递IPv6路由。 预配说明: sysname R1 ospfv3 1router-id 1.1.1.1 # firewall zone Localpriority 15 # interface Serial1/0/0link-protocol pppipv6 enable ipv6 ad…

【Rust自学】7.6. 将模块拆分为不同文件

喜欢的话别忘了点赞、收藏加关注哦(加关注即可阅读全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(・ω・) 7.6.1. 将模块的内容移动到其他文件 如果在模块定义时模块名后边跟的是;而不是代码块&#…

Dockerfile构建SpringBoot镜像并推送到docker公共镜像仓库Docker-hub

💅 写在前面 前期准备工作主要有:准备好必要的环境,确保安装了docker,以及有一个Spring boot项目。 tips:本文所有操作均在宿主机上的 VMware (centos 7)中进行.😽 使用Dockerfile构建SpringBoot镜像 ⭐…

基于Spring Boot + Vue3实现的在线商品竞拍管理系统源码+文档

前言 基于Spring Boot Vue3实现的在线商品竞拍管理系统是一种现代化的前后端分离架构的应用程序,它结合了Java后端框架Spring Boot和JavaScript前端框架Vue.js的最新版本(Vue 3)。该系统允许用户在线参与商品竞拍,并提供管理后台…