vue源码理解之模板编译和组件化

news2024/9/24 7:26:02

一:模板编译
1、模板编译的主要目标是将模板(template)转换为渲染函数(render)

在这里插入图片描述
template => render()

2、模板编译必要性
Vue 2.0需要用到VNode描述视图以及各种交互,手写显然不切实际,因此用户只需编写类似HTML代码的Vue模板,通过编译器将模板转换为可返回VNode的render函数

3、体验模板编译
带编译器的版本中,可以使用template或el的方式声明模板,06-1-compiler.html

(function anonymous(
) {
with(this){return _c('div',{attrs:{"id":"demo"}},[_c('h1',[_v("Vue模板编
译")]),_v(" "),_c('p',[_v(_s(foo))]),_v(" "),_c('comp')],1)}
})

输出结果大致如下:

(function anonymous() {
with(this){return _c('div',{attrs:{"id":"demo"}},[
  _c('h1',[_v("Vue模板编译")]),
  _v(" "),_c('p',[_v(_s(foo))]),
  _v(" "),_c('comp')],1)}
})

元素节点使用createElement创建,别名_c
本文节点使用createTextVNode创建,别名_v
表达式先使用toString格式化,别名_s
其他渲染helpers:src\core\instance\render-helpers\index.js

4、整体流程

compileToFunctions
若指定template或el选项,则会执行编译,platforms\web\entry-runtime-with-compiler.js

5、编译过程
编译分为三步:解析、优化和生成,src\compiler\index.js

6、解析模板编译过程
实现模板编译共有三个阶段:解析、优化和生成

  • 解析 - parse
    解析器将模板解析为抽象语法树,基于AST可以做优化或者代码生成工作。
    调试查看得到的AST,/src/compiler/parser/index.js,结构如下
    在这里插入图片描述
    解析器内部分了HTML解析器、文本解析器和过滤器解析器,最主要是HTML解析器
  • 优化 - optimize
    优化 - optimize
    优化器的作用是在AST中找出静态子树并打上标记。静态子树是在AST中永远不变的节点,如纯文本节点。

标记静态子树的好处:
每次重新渲染,不需要为静态子树创建新节点
虚拟DOM中patch时,可以跳过静态子树

  • 代码生成 - generate
    将AST转换成渲染函数中的内容,即代码字符串。
    generate方法生成渲染函数代码,src/compiler/codegen/index.js
`_c('div',{attrs:{"id":"demo"}},[
_c('h1',[_v("Vue.js测试")]),
_c('p',[_v(_s(foo))])
])`
  • 典型指令的实现:v-if、v-for
    着重观察几个结构性指令的解析过程
    解析v-if:parser/index.js
    processIf用于处理v-if解析
    解析结果:
    在这里插入图片描述
    代码生成,codegen/index.js
    genIfConditions等用于生成条件语句相关代码
    生成结果:
"with(this){return _c('div',{attrs:{"id":"demo"}},[
(foo) ? _c('h1',[_v(_s(foo))]) : _c('h1',[_v("no title")]),
  _v(" "),_c('abc')],1)}"

二:组件化机制
1、组件声明

Vue.component()
initAssetRegisters(Vue) src/core/global-api/assets.js
组件注册使用extend方法将配置转换为构造函数并添加到components选项

2、组件实例创建及挂载
观察生成的渲染函数

"with(this){return _c('div',{attrs:{"id":"demo"}},[
  _c('h1',[_v("虚拟DOM")]),_v(" "),
  _c('p',[_v(_s(foo))]),_v(" "),
  _c('comp') // 对于组件的处理并无特殊之处
],1)}"

3、整体流程
首先创建的是根组件,首次_render()时,会得到整棵树的VNode结构
整体流程:new Vue() => $mount() => vm._render() => createElement() => createComponent()
=》 patch =》createElm =》 createComponent()

4、创建自定义组件VNode

_createElement src\core\vdom\create-element.js
_createElement实际执行VNode创建的函数,由于传入tag是非保留标签,因此判定为自定义组件通过
createComponent去创建
createComponent src/core/vdom/create-component.js
创建组件VNode,保存了上一步处理得到的组件构造函数,props,事件等

注意组件钩子安装和组件tag指定规则

5、创建自定义组件实例
根组件执行更新函数时,会递归创建子元素和子组件,入口createElm

createEle() core/vdom/patch.js line751
首次执行_update()时,patch()会通过createEle()创建根元素,子元素创建研究从这里开始

createComponent core/vdom/patch.js line144
自定义组件创建

// 组件实例创建、挂载
if (isDef(i = i.hook) && isDef(i = i.init)) {
  i(vnode, false /* hydrating */)
}
if (isDef(vnode.componentInstance)) {
  // 元素引用指定vnode.elm,元素属性创建等
  initComponent(vnode, insertedVnodeQueue)
  // 插入到父元素
  insert(parentElm, vnode.elm, refElm)
  if (isTrue(isReactivated)) {
    reactivateComponent(vnode, insertedVnodeQueue, parentElm, refElm)
 }
  return true
}

6、结论:
组件创建顺序自上而下
组件挂载顺序自下而上

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

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

相关文章

扩展卡尔曼滤波在目标跟踪中的应用(2)

上一节的内容中,我们对于扩展卡尔曼EKF算法进行了讲解,今天我们对上一节的内容进行仿真。 话不多说,开整!!! 仿真背景 我们以一个目标的位置信息为例,其状态方程如下所示: X k 0…

黑马程序员前端 Vue3 小兔鲜电商项目——(二)初始化项目

文章目录 了解 Vue3初始化项目创建项目启动项目添加目录Git 管理项目jsconfig.json 配置别名路径 ElementPlus 引入安装配置按需导入测试组件 定制 elementPlus 主题安装sass准备定制化的样式文件自动导入配置 Axios 安装并简单封装安装 Axios基础配置封装请求函数并测试 路由整…

数据血缘分析

引入 做过大数据或者接触过数仓的同学,相信都有听到过数据治理、血缘分析的专业术语。不知道大家有没有思考过以下几个问题: 1、什么是血缘分析?主要分析什么东西? 2、为什么要做血缘分析,主要是为了解决什么痛点?做出来之后有什么价值?如何衡量这些价值? 3、如何做血…

mysql存储过程与函数

文章目录 存储过程概述:创建存储过程调用存储过程存储函数的使用对比存储函数和存储过程存储过程和函数的查看、修改、删除查看修改删除 存储过程概述: 它的思想很简单,就是一组经过 预先编译 的 SQL 语句 的封装。 执行过程:存储过程预先存储在 MySQL …

相对路径与绝对路径(以javaweb项目的html文件为例)

相对路径和绝对路径是用于在文件系统中定位文件或目录的两种方式。 1、两者的概念 绝对路径:是指文件或目录在文件系统中的完整路径,从文件系统的根目录开始一直到文件的具体位置。绝对路径所包含的所有目录都是从根目录开始的,因此&#x…

vue源码理解之Vue批量异步更新和虚拟DOM和Diff算法

一:异步更新队列 1、Vue高效的秘诀是一套批量、异步的更新策略 概念: 事件循环 事件循环:浏览器为了协调事件处理、脚本执行、网络请求和渲染等任务而制定的一套工作机制。 宏任务 代表一个个离散的、独立工作单元。浏览器完成一个宏任务&…

【Visual Studio】Qt 的实时绘图曲线功能,使用 C++ 语言,配合 Qt 开发串口通信界面

知识不是单独的,一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏:Visual Studio。 战斗背景:做了个串口接收界面,用来接收传输过来的信号。但是光用数字显示太单调,需要用图线显示出来。 战略目标&#x…

Java 从入门到精通(续集6)——集合框架

Java 从入门到精通(续集6)——集合框架 在 Java 中,集合是一种用于存储对象的容器,可以方便地进行增删改查等操作。Java 提供了一套完整的集合框架,并且在 Java 5 中引入了泛型,使得集合变得更加灵活。 一、…

Redis哨兵部署

Redis哨兵 单机安装部署 yum install epel-release -yYum install redis -yMkdir /root/redisCd /root/rediscp /etc/redis.conf .cp redis.conf redis_6379.confcp redis.conf redis_6380.confcp redis.conf redis_6381.conf vim redis_6379.conf 1.配置redis.conf文件中的…

极致呈现系列之:Echarts水球图的灵动魅力

目录 水球图简介什么是水球图水球图的特点和用途水球图的安装和引入水球图的常用配置项创建基本的水球图自定义水球图样式水球图中的shape属性使用SVG代码自定义水球图水球图简介 什么是水球图 水球图是一种通过一个圆形的容器来展示数据的图表类型。它以水球作为图形的基本元…

【C++篇】封装类和对象

友情链接:C/C系列系统学习目录 知识总结顺序参考C Primer Plus(第六版)和谭浩强老师的C程序设计(第五版)等,内容以书中为标准,同时参考其它各类书籍以及优质文章,以至减少知识点上的…

【机器学习】十大算法之一 “逻辑回归”

作者主页:爱笑的男孩。的博客_CSDN博客-深度学习,活动,python领域博主爱笑的男孩。擅长深度学习,活动,python,等方面的知识,爱笑的男孩。关注算法,python,计算机视觉,图像处理,深度学习,pytorch,神经网络,opencv领域.https://blog.csdn.net/Code_and516?typeblog个…

MindSpore-FCOS模型权重迁移推理对齐实录

准备工作 环境: wsl2 Ubuntu 20.04 mindspore 2.0.0 python 3.8 pytorch 2.0.1 cpu 基于已有的mindspore FCOS项目和FCOS官方pytorch权重来做迁移, FCOS官方pytorch实现 FCOS_imprv_R_50_FPN_1x权重 MindSpore FCOS项目链接 该代码是mindspore1.6实现…

【加强版】SAX解析XML返回对应格式的Map对象(解决元素递归嵌套)

SAX解析XML返回对应格式的Map对象_辛丑年正月十五的博客-CSDN博客 前言 上篇文章实现了xml元素节点的解析并返回了对应格式的Map对象,但是遗留了一个问题,就是当xml中的元素存在递归嵌套时就解析不了,因为qname属性会重复,导致后…

DDD软件架构领域驱动设计

目录 1. DDD概述1.1 软件开发的困境1.2 DDD的来源及简介1.2.1 DDD设计方法 1.3 DDD解决了什么问题1.3.1 沟通问题1.3.2 代码质量问题 1.4 模型和建模1.4.1 什么是模型 1.5 统一语言(UBIQUITOUS LANGUAGE)1.6 什么是DDD 2. 传统开发模式2.1 基础知识回顾2…

Debian12.0.0更换系统语言中文到英文

6月10号,Debian12.0.0更新,想尝尝鲜,在虚拟机里安装好,想将中文改为英文,因为Terminal下输入命令,中文切换麻烦。 一、步骤如下 #1、查看当前语言环境 env | grep LANG #2、en表示语言,US表示…

欧科云链在GEF论坛发起圆桌:监管科技与Web3合规发展图景与展望

6月15日,欧科云链在格林威治经济论坛发起了一场题为“监管科技与Web3合规发展图景与展望”的圆桌会议,此次会议由中国香港贸易发展局副执行董事PatrickLau博士主持。Stratford Finance首席执行官Angelina Kwan,BC科技集团有限公司董事会副主席…

[Web前端] Servlet及应用

文章目录 前言1、简介1.1、Servlet 架构1.1.1、Servlet 任务1.1.2、Servlet 包 1.2、Servlet 环境设置1.2.1、设置 Web 应用服务器:Tomcat 1.3、Servlet 生命周期1.3.1、init() 方法1.3.2、service() 方法1.3.3、doGet() 方法1.3.4、doPost() 方法1.3.5、destroy() …

采集发布到WordPress 特色图片(缩略图)无法显示

采集的数据发布到wordpress系统网站,文章内容是正常的,但是在列表页的缩略图(特色图片)却是显示失败。 这种情况有多种问题都可以造成的,可按照以下步骤逐一排查: 目录 1. 发布映射值是否正确 2. 与主题…

【Python 基础篇】Python 字符串以及字符串常用函数

文章目录 导言一、字符串基础二、字符串操作1、字符串拼接2、字符串格式化3、字符串常用函数len()lower()upper()strip()split()join()replace()find()count() 三、条件控制与字符串总结 导言 字符串是计算机编程中常用的数据类型之一。在 Python 中,字符串是由字符…