vue-vapor 的 IR 是个啥

vapor 模式下的 vue 是如何实现无虚拟 dom 还能去精准操控 dom ?

答案应该是 IR 其中的一个属性 block,block 里面记录了动态节点,而这个 IR 又是在编译阶段就产生了

本期文章就带大家初步认识 vapor 下的 ir

我们可以看到源码 packages\compiler-vapor\src\compile.ts 目录下有个 compile 函数

本篇源码分析基于 core 的 tag: v3.6.0-alpha.2

可以看到 ir 为 transform 的产物

若之前看过 v3(vdom)源码的小盆友这里肯定会觉得似曾相识

没错,compiler-core 包下面的 src/compile.ts 文件也有类似这样的代码,如下:

这里的 transform 是针对 baseParse 后的 ast 进一步解析,所谓进一步解析就是去解析 v- 指令(主要作用),然后拿到最终的 ast 给到 generate 去生成 render 函数

比如这里有个很简单的 template :

vue 复制代码
<template>
  <div class="user-list">
    <h2>{{ title }}</h2>

    <span v-if="false">Dolphin</span>
  </div>
</template>

在传统 v3(vdom)下,被解析成 render 函数如下:

js 复制代码
import { toDisplayString as _toDisplayString, createElementVNode as _createElementVNode, openBlock as _openBlock, createElementBlock as _createElementBlock, createCommentVNode as _createCommentVNode } from "vue"

export function render(_ctx, _cache, $props, $setup, $data, $options) {
  return (_openBlock(), _createElementBlock("template", null, [
    _createElementVNode("div", { class: "user-list" }, [
      _createElementVNode("h2", null, _toDisplayString(_ctx.title), 1 /* TEXT */),
      false
        ? (_openBlock(), _createElementBlock("span", { key: 0 }, "Dolphin"))
        : _createCommentVNode("v-if", true)
    ])
  ]))
}

我们可以看到 baseParse 后的 ast 产物已经产生了 rawName 等 v- 指令的名称

如图,span 标签同级属性 props 数组的 item 会包含一个值为 v-if 的 rawName 属性

现在我们把断点挪到 transform 之后,你会发现此时的 ast 结构里面的 v-if 已经不见了,里面的值已经被解析出来了(本质是 processIf)

为了对比 这里的 ast 和稍后的 ir,我们把此时的 ast 结构贴出来

现在我们在 Template Explorer 的 options 中勾选 vapor 选项,我们来到 vapor 模式下的 template 解析,看到 ir 如下

可以看到 IR 具有 block 属性,里面标记了 dynamic,operation 属性,我们仔细看会发现里面 ir.node 也是一个 ast

由此可见,ir 直接描述了运行时的操作,可以理解为这玩意儿直接描述了要执行的 dom 操作

js 复制代码
Template → AST(语法树) 
       ↓
   ✨ IR(中间表示)
       ↓
Runtime Code(mount/update 逻辑)

总结

ir (Intermediate Representation)其实就是 templated AST 和 最终生成代码之间的抽象结构,可以理解为中间语言

它把 模板 转换成了 结构清晰 ,带有运行时操作信息的精细化对象

再进一步总结就是 Vapor 编译器内部用于描述 dom 和 响应绑定关系的结构,有了它才能跳过 vdom

最后丢出一张 vapor 和 v3(vdom) 编译对比图

相关推荐
現実逃避と2 小时前
WIN10 Edge连续关闭多个标签页导致资源管理器崩溃临时解决办法
前端·edge
jay神2 小时前
基于 FastAPI + Vue 的宠物领养管理系统
前端·vue.js·python·毕业设计·fastapi·宠物
一杯奶茶¥3 小时前
水果销售网站 CRM客户信息管理系统 超市管理系 酒店管理系统 健身房管理系统 在线音乐网站 校园招聘系统
java·vue.js·spring boot·mysql·spring·java项目
lichenyang4533 小时前
鸿蒙 Web 容器(五·完结):闭环回传、容器治理,兼谈 AtomicServiceEnhancedWeb
前端
lichenyang4533 小时前
鸿蒙 Web 容器(四):ArkTS 拿到请求后,怎么「按 action 找能力」?
前端
lichenyang4533 小时前
鸿蒙 Web 容器(三):H5 怎么「调」到 ArkTS?
前端
代码不加糖3 小时前
Proxy能够监听到对象中的对象的引用吗?
开发语言·前端·javascript
英勇无比的消炎药3 小时前
一站式搞定品牌风格:TinyRobot 主题定制从入门到精通
vue.js
光影少年3 小时前
react 原理与进阶
前端·react.js·掘金·金石计划
kyrie283 小时前
Vue 全套性能优化方案
前端