Vue2.x源码解析(二)

news/2025/3/15 3:44:05/

Compiler 函数

在Vue 2.0 中,Compiler 函数是 Vue 编译器的核心,它负责将 HTML 模板编译成渲染函数。这个函数被用于创建 Vue 实例或者组件。下面是 Compiler 函数的伪代码实现:

function compile (template) {// 把模板转换成 AST(抽象语法树)const ast = parse(template)// 对 AST 进行静态优化optimize(ast)// 把 AST 转换成渲染函数const code = generate(ast)// 把渲染函数打包成可执行的函数const render = new Function(code)// 返回渲染函数return {render,staticRenderFns: []}
}

上面的代码是 Compiler 函数的伪代码实现,它包括以下三个步骤:

  1. 把模板转换成 AST(抽象语法树) 首先,Compiler 函数会调用 parse 函数,把 HTML 模板转换成 AST。AST 把我们的模板编译成一组抽象的节点树,每个节点表示HTML中的一个元素或者属性,并且包含有关该元素或属性的详细信息。

  2. 对 AST 进行静态优化 接下来,Compiler 函数会对 AST 进行静态优化,帮助我们减少渲染函数的成本和优化性能。这一步通常包括静态节点提取(Static Node Hoisting)、静态属性提取(Static Property Hoisting)和表达式提取(Expression Hoisting)等。

  3. 把 AST 转换成渲染函数 最后,Compiler 函数会调用 generate 函数,把 AST 转换成渲染函数的字符串代码。

  4. 把渲染函数打包成可执行的函数 render 函数的代码生成后,会被封装成一个新的 Function 对象,赋值给 Vue 实例的 $options 属性。这样,每次调用 render 函数时,就会执行新创建的 Function 对象,并返回渲染结果。

这就是 Compiler 函数的主要作用。它将提供一个包含渲染函数和静态节点数组的对象,然后我们就可以用它来创建 Vue 实例或它的子组

Runtime 函数

Runtime 函数是用于生成虚拟DOM并处理渲染的函数。它通过创建虚拟DOM、执行diff算法以及最终将虚拟DOM转换成实际的DOM,实现了Vue的整个渲染流程。在对Vue模板进行编译并且生成渲染函数后,Runtime 函数实际上是直接调用渲染函数的。

function mount(rootComponent, el) {// 创建虚拟DOMconst vnode = createVNode(rootComponent)// 创建渲染上下文const context = createRenderContext()// 渲染虚拟DOMrender(vnode, el, context)
}function render(vnode, container, context) {if (isString(vnode) || isNumber(vnode)) {// 处理文本节点const textNode = createTextNode(vnode)insert(container, textNode)} else if (isObject(vnode) && vnode._isVNode) {// 处理虚拟DOM节点const prevVNode = context.prevVNodeif (sameVnode(vnode, prevVNode)) {// 更新节点patch(prevVNode, vnode, container, context)} else {// 渲染新节点mountNode(vnode, container, context)}}
}function patch(prevVNode, nextVNode, parent, context) {// 更新节点内容updateAttrs(prevVNode, nextVNode)updateClass(prevVNode, nextVNode)updateProps(prevVNode, nextVNode)updateChildren(prevVNode, nextVNode, parent, context)
}function mountNode(vnode, container, context) {if (isFunction(vnode.type)) {// 处理组件节点mountComponent(vnode, container, context)} else {// 处理普通节点mountElement(vnode, container, context)}
}function mountElement(vnode, container, context) {// 创建DOM节点const el = createDomElement(vnode)// 挂载子节点mountChildren(vnode, el, context)// 将DOM节点插入到父节点中insert(container, el)// 更新渲染上下文,保存当前节点context.prevVNode = vnode
}

上面的代码是 Runtime 函数的伪代码实现,它包括以下几个步骤:

  1. 创建虚拟DOM   在运行时,首先会创建一个虚拟DOM节点,并确保它符合VNode接口的标准格式。

  2. 创建渲染上下文  接着创建了一个渲染上下文,它包括一些用于处理渲染的核心函数。这个上下文对象包括了之前我们提到的prevVNode,用于在未来的更新中比较节点差异。

  3. 渲染虚拟DOM   接下来,我们开始执行实际的渲染过程。我们检查我们的vnode是否是字符串或数字类型的,如果是就创建文本节点并添加到父节点中,如果不是,我们看vnode是否应该被视为虚拟DOM节点。如果是,我们检查prevVNode是否与nextVNode相同,如果不同,我们会调用mountNode()方法,以根据新的vnode创建新节点。如果它们相同,我们会调用patch()方法更新DOM节点。

  4. 更新节点内容   与新节点不同的是,在此处由patch()方法做出的更改通常包括更新节点本身的属性和样式。在此处,我们通常检查当前节点的属性和下一个节点的属性是否相等,并相应地设置节点属性。

  5. 更新子节点    当我们之前更新当前节点的属性时,我们还需要考虑它的子节点。我们会递归地调用patch()方法来确保我们的父级节点的所有子节点都已更新。

  6. 创建DOM节点   创建Dom节点时,我们通常会根据VNode的信息来确定节点的特定类型和class,并创建相应的HTML节点。

  7. 挂载子节点 然后我们把虚拟子节点挂载到HTML节点上。

  8. 将DOM节点插入到父节点中 最后,我们会把DOM节点插入到父节点的HTML树中,并根据节点的类型进行合适的操作。

总之,Runtime 函数是负责生成虚拟DOM、执行diff算法和最终将虚拟DOM转换成实际的DOM的重要函数,是Vue框架的一个核心功能模块。


http://www.ppmy.cn/news/68481.html

相关文章

随机变量X,分布函数X~F(x)的理解。

1.随机变量X 1.通常认知的"x"与随机变量X 我们通常意义上的 x 是自变量,y f(x) 中的自变量。 但是 X 更多意义是 对应法则 " f " ,X完整写法是 X(ω) ω ∈ Ω。 X这个对应法则,可以将样本点映射到实数轴上。 那么X这…

verflow属性的常用值详解

什么是overflow 在CSS中,overflow是“溢出”的意思,该属性规定当内容溢出元素框时发生的事情,设置内容是否会被修剪,溢出部分是否会被隐藏;例如当属性值设置为“visible”则内容不会被修剪,为“hidden”则内…

vuex详解及模块化

私人博客 许小墨のBlog —— 菜鸡博客直通车 系列文章完整版,配图更多,CSDN博文图片需要手动上传,因此文章配图较少,看不懂的可以去菜鸡博客参考一下配图! 系列文章目录 前端系列文章——传送门 后端系列文章——传送…

Spark大数据处理讲课笔记4.3 Spark SQL数据源 - Parquet文件

文章目录 零、本讲学习目标一、Parquet概述二、读取和写入Parquet的方法(一)利用parquet()方法读取parquet文件1、读取parquet文件2、显示数据帧内容 (二)利用parquet()方法写入parquet文件1、写入parquet文件2、查看生成的parque…

【Vue】学习笔记-Vue CLI $nextTick 过渡与动画

$nextTick 这是一个生命周期钩子 this.$nextTick(回调函数) 在下一次DOM更新结束后执行其指定的回调 什么时候用:当数据改变后,要基于更新后的新DOM进行某些操作时,要在nextTick所指定的回调函数中执行。 使用$nextTick优化Todo-List src/co…

Redis高级数据结构HyperLogLog

HyperLogLog(Hyper[ˈhaɪpə(r)])并不是一种新的数据结构(实际类型为字符串类型),而是一种基数算法,通过HyperLogLog可以利用极小的内存空间完成独立总数的统计,数据集可以是IP、Email、ID等。 如果你负责开发维护一个大型的网站,有一天产品…

DOM事件模型与事件委托

事件 JS与HTML之间的交互通过事件实现。 事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。 可以使用监听器来预定事件,以便事件发生时执行相应的代码。这种在传统软件工程中被称为观察者模式 事件流 事件流描述的是从页面中接受事件的顺序 事件冒泡 微软…

Educational Codeforces Round 145 (Rated for Div. 2) 题解

总结:这一场挺不容易的,思路也是挺奇特的,就是做上去感觉怪怪的,没有一点感觉 A. Garland 思路:不能连续操作两个相同颜色的灯泡,所以记录灯泡的颜色的数量,因为只有四个灯泡,便可…