Vue3中的执行流程思路分析-流程图

目录
  • 一. 前言
  • 二. Vue3 思路分析
    • 1. createRender(options)
    • 2. createApp
    • 3. app.mount(‘#app’)
    • 4. render(vnode, container)
    • 5. patch(n1, n2, container)
    • 6. processComponent
    • 7. mountComponent
    • 8. setupRenderEffect
    • 9. patch
    • 10. processElement mountElement
  • 三. 结尾

一. 前言

本文只在为大家梳理完整的vue3代码执行流程,从创建createApp到渲染为真实dom节点。

在读后续文章时,请大家参考以下流程图食用,好了废话不多说,开整!!!

(本文主要为梳理思路,不展示太多源码。)

二. Vue3 思路分析

提示:一定要按照流程图哦!!!

1. createRender(options)

我们创建vue3时,最常见的一个api就是createApp,但是在执行createRender时,createApp还没有被创建,那该方法是干什么的呢,传入的参数有是什么呢?我们接着往下看。

options:源码中也叫做 nodeOps,其实就是vue3自己重新封装的一些dom操作,例如insert、remove、createElement等,在pc端,其实就是利用domcument下的一些原生方法实现

优点:那就有人要问了,为什么要重新封装

首先有这么几点好处:

  • 1.封装后使用更清楚简短,方便调用
  • 2.最重要的一点,那就是将vue的渲染工作与dom操作完全解耦,这样更适合多端操作,只需要重入对应的nodeOps即可,自己重新封装对应的dom操作方法,比如移动端等

从流程图来看,调用该方法之后,返回三个Api,其中我们只关心两个重要的也是常用的createApp、render
我们继续往下看。

2. createApp

这个方法大家应该都不陌生,该方法传入一个根组件rootComponent,但是并没有做任何处理,在该方法中主要任务创建了一个全局对象app

我们来看下app中常见的几个api

App

  • use: 用来注册插件,为vue实现扩展,如vueRouter、vuex、pinia等
  • component: 用来注册全局组件,可以在任意组件中使用
  • 注意:以上方法都应该在mount挂载之前执行
  • mount: 这一步也就是最关键的一部,开始执行将组件渲染的第一步,我们继续往下看

3. app.mount(‘#app’)

从流程图中我们可以看到,挂载中主要执行了两个操作

  • 1.createVNode
  • 首先将我们传入的根组件传入到createVNode方法中,将组件包装成vnode对象并且返回
  • 2.render(vnode, rootContainer)
  • 此处的render就是在前边执行createRender时返回的方法,我们在此处继续执行它,并且传入两个参数,第一个是我们包装后的rootComponent,第二个是挂载传入真实domrootContainer

好了,mount执行完毕,我们进入到render中继续向下执行

4. render(vnode, container)

在此方法中,做了一个最重要的工作就是将已经渲染的vnode,也可以称之为旧的vnode保存到container._vnode上,然后调用

patch(container._vnode|| null, vnode)

这样,就形成了新旧vnode,也就有了diff的说法,让我们进入到patch方法中。

5. patch(n1, n2, container)

patch中文意思打补丁,也就描述了他的用法,对比新旧vnode,也就是我们常说的diff算法,将新的vnode渲染到真实dom中。

该方法中主要分为了两大分支,当然还有其它,我们就先忽略,跟着主线走下去

  • 1.processComponent
  • 当传入的n2为组件时进入这个分支
  • 2.processElement
  • 当传入的n2为元素类型时走该分支

我们先进入processComponent来对传入的rootComponent进行处理

6. processComponent

该方法中又出现了两个分支

  • mountComponent: 在第一次挂载时执行update
  • Component: 组件跟新时执行

我们接着往下看

7. mountComponent

该组件中执行了三个主要的方法,我们一个个来看

  • createInstance:首先是创建实例,我们自定义的每个组件第一次渲染时都会走该分支,为每个组件定义了一个组件实例instance,因此vue3中就有了一个方法getCurrentInstance来访问每个组件的实例。
  • setupComponent:这一步非常重要,该方法接受一个参数,也就是刚刚创建的组件实例,在这一步中,调用了我们传入的setup,所以,我们调用的所有方法,也就是在这被执行,比如reactive,ref,生命hook,watch,computed等,之后将setup调用的结果保存到instance中的setupState属性中。
  • setupRenderEffect:在一切准备工作都做完之后,接下来就该进行渲染,我们继续进入到该方法中。

8. setupRenderEffect

该方法中创建了一个componentUpdateFn组件更新函数,也就是在这,实现了真正的响应式处理,在setupComponent中,执行了setup,在这我们对数据进行了响应式处理,利用reactive/refs对数据实现了处理,在get中收集依赖,set中更新依赖。

在创建好componentUpdateFn方法之后,我们创建了一个新的对象

new ReactiveEffect(componentUpdateFn),之后我们执行返回对象的run方法,其中执行了传入的componentUpdateFn函数,在componentUpdateFn中,我们首先对组件的render或者template进行处理,也就对我们用到了响应式数据进行了get,由此,将ReactiveEffect收集到对应数据的依赖中,在每次数据修改时,执行componentUpdateFn,之后,在挂载函数中继续执行patch,传入处理后的render或者temeplate,至此回到patch中,进行递归。

9. patch

此时,传入的是根标签包装后的vnode,所以,此次走的分支为processElement,让我们跟着流程图继续往下看。

10. processElement mountElement

在该方法中,我们利用我们传入的nodeOpts,也就是dom操作方法,将vnode渲染为真实的dom,此时,终于将组件渲染到页面上,同时将转换的真实dom存放在vnode.el上。

patchElement
该方法也就是diff算法的核心,当组件更新之后,通过diff算法,将新的vnode渲染到页面上。

三. 结尾

至此,vue3从创建到渲染的所有流程执行结束,在数据更新之后,我们通过执行依赖,也就是componentUpdateFn函数,重复之前的步骤,重新执行组件的render函数获取根标签,传递给patch,然后更新页面,一直重复该过程。也就实现了页面的改变。直到网页关闭。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • 绘制flowable 流程图的Vue 库使用详解

    目录 引言 workflow-bpmn-modeler 注册 bpmnModeler 组件 muheflow-bpmn-modeler 引言 之前松哥发了一篇文章和小伙伴们介绍了前端的 bpmn.js 这个库,利用这个库我们可以自己将绘制流程图的功能嵌入到我们的项目中. 然而,这个库默认是给 Camunda 设计的,所以画出来的流程图导出来的 XML 文件无法直接使用,必须要做一些深度定制,才能将 XML 文件转为 Flowable 流程引擎可用的 XML 文件.这个深度定制太太太麻烦了. 所以

  • vue+jsplumb实现工作流程图的项目实践

    最近接到一个需求——给后台开发一个工作流程图,方便给领导看工作流程具体到哪一步. 先写了一个demo,大概样子如下: 官网文档Home | jsPlumb Toolkit Documentation 先安装插件 npm install jsplumb --save 安装panzoom,主要用于鼠标滚轮缩放流程图 npm install panzoom --save 在需要的页面引入插件 import panzoom from 'panzoom' import { jsPlumb } from '

  • vue中使用gojs/jointjs的示例代码

    因为公司项目需求,要画出相关业务的流程图,以便客户了解自己身处何处 搜索框输入 "前端流程图插件",查了很多资料,总结一下有以下几种 flow-chart 代码写法繁琐,不是json就可以解决,效果也比较丑,PASS darge-d3 github :https://github.com/dagrejs/dagre-d3 效果图 下载里面的demo,改一下json就可以了 // States var states = [ "NEW", "SUBMITTED

  • vue + gojs 实现拖拽流程图效果

    目录 一.流程图效果 二.为什么选go.js流程图插件去开发项目? 三.项目开发 四.当前画布的监听事件名称包括 五.迭代篇 (一).项目的迭代. (二).整体用的js方法 (三).功能分析 一.流程图效果 最近一段时间在研究go.js,它是一款前端开发画流程图的一个插件,也是一个难点,要说为什么是难点,首先,它是依赖画布canvas知识开发.其次,要依赖于内部API开发需求,开发项目需求的时候就要花费大量的时间去熟悉go.js的API,然后才能进行开发.话不多说,我就先把我最近做的项目案例效果

  • GOJS+VUE实现流程图效果

    前言及展示 在项目中需要根据传过来的数据画出流程图,采用了GOJS插件,功能很全面,可以根据自己的需要调整,不过建议简单的流程图还是自己手写一个组件,更加便于维护和变换.有一点需要注意的是,GOJS是需要收费的,有水印,虽然可以手动去掉,但是公司用的话还是需要买.GOJS的官网上有关于在VUE中应用GOJS的小例子:Minimal GoJS Sample in Vue.js.推荐看一下,可以解决大部分简单需求,这个例子可以满足你并行步骤数比较固定的二叉树画法的流程图. 这是官网的例子,其中模块,

  • vue 中引用gojs绘制E-R图的方法示例

    首先,在vue项目中安装gojs的依赖包,并在项目中引入. 创建tablePreview.vue <style> #sample{ position: relative; margin: 20px; } #myOverviewDiv { position: absolute; width:225px; height:100px; top: 10px; left: 10px; background-color: aliceblue; z-index: 300; /* make sure its

  • Vue3中的执行流程思路分析-流程图

    目录 一. 前言 二. Vue3 思路分析 1. createRender(options) 2. createApp 3. app.mount(‘#app’) 4. render(vnode, container) 5. patch(n1, n2, container) 6. processComponent 7. mountComponent 8. setupRenderEffect 9. patch 10. processElement mountElement 三. 结尾 一. 前言 本

  • MyBatis Plus插件机制与执行流程原理分析详解

    MyBatis Plus插件 MyBatis Plus提供了分页插件PaginationInterceptor.执行分析插件SqlExplainInterceptor.性能分析插件PerformanceInterceptor以及乐观锁插件OptimisticLockerInterceptor. Mybatis 通过插件 (Interceptor) 可以做到拦截四大对象相关方法的执行 ,根据需求完成相关数据的动态改变. 四大对象是: Executor StatementHandler Parame

  • vue2与vue3中生命周期执行顺序的区别说明

    目录 vue2与vue3中生命周期执行顺序区别 生命周期比较 简单例子说明 三种情况下的生命周期执行顺序 1.单页面下生命周期顺序 2.父子.兄弟组件的生命周期顺序 3.不同页面跳转时各页面生命周期的执行顺序 vue2与vue3中生命周期执行顺序区别 生命周期比较 vue2中执行顺序 beforeCreate=>created=>beforeMount =>mounted=>beforeUpdate =>updated=>beforeDestroy=>destro

  • Mybatis执行流程、缓存原理及相关面试题汇总

    目录 一.Mybatis执行流程 二.Mybatis缓存 1.一级缓存 2.二级缓存 3.缓存原理 三.相关面试题 1.为什么说 Mybatis 是半自动ORM映射工具?它与全自动的区别在哪里? 2.简述一下Mybatis的执行流程吧 ? 3.说一下Mybatis的优缺点 ? 4.#{} 和 ${} 的区别是什么 ? 5.Mybatis的动态SQL有什么作用?执行原理是什么?有哪些常用标签? 总结 一.Mybatis执行流程 具体分析Mybatis是如何操作数据库的! 1.定义我们的核心配置文件

  • Mybatis中的PageHelper的执行流程分析

    PageHelper Mybatis的执行流程 mybatis中首先要在配置文件中配置一些东西 然后根据这些配置去创建一个会话工厂 再根据会话工厂创建会话,会话发出操作数据库的sql语句 然后通过执行器操作数据 再使用mappedStatement对数据进行封装 这就是整个mybatis框架的执行情况. 插件的执行 它主要作用在Executor执行器与mappedeStatement之间 也就是说mybatis可以在插件中获得要执行的sql语句 在sql语句中添加limit语句,然后再去对sql

  • 解析HashMap中的put方法执行流程

    目录 引言 HashMap底层数据结构 put方法的执行流程 总结 引言 在Java集合中,HashMap的重要性不言而喻,作为一种存储键值对的数据结构,它在日常开发中有着非常多的应用场景,也是面试中的高频考点,本篇文章就来分析一下HashMap集合中的put方法. HashMap底层数据结构 先来了解一下HashMap底层的数据结构,它实质上是一个散列表,在数据结构课程中,我们应该都学习过散列表,它是通过关键码值而直接进行访问的一种数据结构,比如存储这样的一个序列:5,12,7,6,1,3.我

  • vue3中ref绑定dom或者组件失败的原因及分析

    目录 vue3 ref绑定dom或者组件失败原因分析 场景描述 ref绑定失败情况举例 解决方案 vue3组合式API的v-for及ref绑定DOM 总结 vue3 ref绑定dom或者组件失败原因分析 场景描述 在vue3中经常用到使用ref绑定组件或者dom元素的情况,很多时候,明明使用ref绑定了相关组件,但是经常ref绑定失败的情况. ref绑定失败情况举例 ref绑定失败的绝大多数情况是,在ref和组件绑定的时候,该组件还未渲染,所以绑定失败. 或者组件刚开始未渲染,ref未绑定,当组

  • laravel 框架执行流程与原理简单分析

    本文实例讲述了laravel 框架执行流程与原理.分享给大家供大家参考,具体如下: 1.index.php $app = require_once __DIR__.'/../bootstrap/app.php'; $kernel = $app->make(Illuminate\Contracts\Http\Kernel::class); $response = $kernel->handle( $request = Illuminate\Http\Request::capture() ); 2

  • Vue3中emits与attrs的区别分析

    目录 结论 实践分析 扩展 总结 结论 当在父组件自定义事件,若没有在子组件中声明时,将自动绑定在父组件的$attrs上:而当在子组件声明时,则不会在父组件的$attrs上出现 实践分析 为了验证emits和attrs的区别,我们构造这样的组件结构 <div> <com-one-vue/> </div> <div> <com-one-vue/> </div> 其具体的Vue文件及代码为(注意,以下语法均采用 setup语法糖 ): A

  • node中http模块的使用及执行流程

    在node中http有什么作用 http这个模块的职责就是帮你创建编写服务器 执行流程 1. 加载http模块 const http = require('http') 2. 使用http.createServer方法创建一个web服务器 返回一个server实例 const server = http.createServer() 3.提供对数据的服务 发请求 接受请求 处理请求 返回(发送响应) 注册request请求事件,当客户端请求过来就会自动触发request请求事件然后就会执行第二个

随机推荐