闽公网安备 35020302035485号
codegen 阶段根据 AST 生成对应的 render 函数字符串。
<template>
<div>
<p>{{ message }}</p>
<button @click="toggle">{{ isShown ? 'Hide' : 'Show' }}</button>
</div>
</template>
解析器 (parse.ts) 将模板字符串解析成 AST。所有的 AST 节点定义都在 compiler-core/ast.ts 文件中,下面是一个元素节点的定义:export interface BaseElementNode extends Node {
type: NodeTypes.ELEMENT // 类型
ns: Namespace // 命名空间 默认为 HTML,即 0
tag: string // 标签名
tagType: ElementTypes // 元素类型
isSelfClosing: boolean // 是否是自闭合标签 例如 <br/> <hr/>
props: Array<AttributeNode | DirectiveNode> // props 属性,包含 HTML 属性和指令
children: TemplateChildNode[] // 字节点
}
转换器对 AST 进行优化和转换。AST结构:{
type: 1, // 表示根节点
tag: 'div',
children: [
{
type: 1,
tag: 'p',
children: [
{
type: 2, // 表示文本节点
content: '{{ message }}'
}
]
},
{
type: 1,
tag: 'button',
children: [
{
type: 2,
content: '{{ isShown ? "Hide" : "Show" }}'
}
],
props: [
{
type: 7, // 表示事件绑定
name: 'click',
value: {
type: 4, // 表示表达式节点
content: 'toggle'
}
}
]
}
]
}
transfromconst _hoisted_1 = { class: "text-red" };
const _hoisted_2 = { key: 0 };
// 堆代码 duidaima.com
export function render(_ctx, _cache) {
return (
openBlock(),
createElementBlock("div", null, [
createVNode("p", null, toDisplayString(_ctx.message), 1 /* TEXT */),
createVNode(
"button",
{
onClick: _cache[0] || (_cache[0] = (...args) => _ctx.toggle && _ctx.toggle(...args))
},
toDisplayString(_ctx.isShown ? "Hide" : "Show"),
1 /* TEXT */
)
])
);
}
上述代码最后返回一个 render() 函数,作用是生成对应的 VNode。