1、compiler module: 编译器
包含compiler-core、compiler-dom 解析html,将html模板编译为render函数,以及生成AST。在以下两个时刻执行:
- vue项目打包编译时(compile time)
- 浏览器运行时(runtime)
编译器本质就是:输入是模板字符串,输出是用以生成vnode的渲染函数 (无论是模板还是jsx都需要经过编译,那么是之间编译成VNode树,还是编译成由h
函数组成的调用合集好呢?这个其实很难说,但可以肯定的一点试,我们将可共用、灵活、复杂的逻辑封装成函数,交给runtime,这能够大大降低编译器的书写难度,甚至经过编译器生成的代码也具有一定的可读性):
2、renderer module: 渲染模块(运行时)
包含runtime-core、runtime-dom 负责视图渲染,在三个时机,将视图渲染到页面上:
- render phase, 执行compiler的产物即渲染函数,生成VDOM。
- mount phase, 利用VDOM,创建页面html
- patch phase,数据模型一旦变化,渲染函数会再次被调用,生成新的VDOM,然后diff更新视图html
3、reactivity: 响应式模块
将数据变成可以被监听的响应式对象
4、整体流程:
- compiler 模块将html模板,编译为渲染函数
- reactivity模块将数据对象初始化为响应式数据对象
- renderer模块:
- RenderPhase : 渲染模块使用渲染函数根据初始化数据生成虚拟Dom
- MountPhase : 利用虚拟Dom创建视图页面Html
- PatchPhase:数据模型一旦变化渲染函数将再次被调用生成新的虚拟Dom,然后做Dom Diff更新视图Html
5、vue3中的渲染函数 and 辅助创建VNode的h
函数
一个vue组件,最核心的东西是render
函数,剩余的其他内容,如data
、props
等都是为了render
函数提供数据来源服务的。render
函数的作用是: 产出VNode,也可以说vue组件的本质是产出VNode(为何组件不直接产出html string
?其原因是VDom
带来了分层设计,它对渲染过程的抽象,是的框架可以渲染到web以外的平台,以及实现SSR
等)
- 当使用模板语法时候,编译器会帮助我们生成渲染函数。
- 然而在一些场景中,真的需要 JavaScript 的完全编程的能力。这时可以直接用渲染函数
- 渲染函数需要返回一个VNode,如果直接手写VNode,也太反人类了,还好有个
h
函数帮助我们!(h
函数其实就是专门用于创建 VNode 对象的函数封装)
6. vue源码项目结构
- compiler-core: 编译器核心(平台无关)
- compiler-dom: 针对浏览器的编译模块
- compiler-sfc: 用以编译单个vue 文件
- compiler-ssr: 针对服务器渲染的编译模块
- reactivity: 响应式系统
- runtime-core:运行时核心(平台无关)
- runtime-dom: 针对浏览器的运行时,包括dom api、属性、事件处理
- runtime-test: 用于测试,可以用于自定义渲染器测试
- server-renderer: 用于服务器端渲染
- shared: 多个包之间共享内容
- size-check: 用于检测包大小
- template-explorer: 用以调试编译器输出的工具包
- vue: vue完整版本,包含运行时和编译器
- vue-compat: 提供了可配置的vue2兼容 行为
runtime-core核心:
- 定义创建VNode方法,包含h函数。
- diff VNode。
- 生成renderer(renderer作用:根据VNode,调用增删改查API进行渲染)
runtime-dome核心:
提供web渲染的增删改查API