流式渲染模式
Stream UI 提供两种解析模式。
Fast 模式(mode="fast")
使用 FAST_MODE_TAG_REGEX 单次正则扫描,匹配所有标签和文本段。
正则: <([A-Za-z][\w-]*)(?:\s+[^>]*)?(?:(/>)|(?:>)([^]*?)(?:<\/\1>|$))
└─标签名──┘ └──属性──┘ └自闭合┘ └──内容─┘ └──闭合标签──┘- 单遍扫描,不维护栈
- 不处理嵌套标签(嵌套标签会被扁平化)
- 标签未闭合时,
match[3]可能捕获到意外的后续文本 - 适合历史消息等不需要嵌套交互的场景
Accurate 模式(mode="accurate",默认)
基于栈的深度优先解析,分两阶段:
阶段 1:parseAccurateStream
输入: "<outer><inner lang='ts'>code</inner></outer>"
栈操作:
[root] # 初始化
[root, outer] # 遇到 <outer>,入栈
[root, outer, inner] # 遇到 <inner>,入栈
[root, outer] # 遇到 </inner>,出栈,标记 isClosed=true
[root] # 遇到 </outer>,出栈关键行为:
- 嵌套支持:标签按栈结构构建树
- 标签交错检测:闭合标签
</a>时,若栈顶不是<a>,强制闭合中间的标签,在 console 输出警告 - 孤立闭合检测:闭合标签在栈中无匹配开放标签时,输出警告并丢弃
- 自闭合标签:以
/>或/ >结尾的标签立即标记isClosed: true,不入栈 - 流式处理:未闭合的标签保留在栈中,
isClosed为false
阶段 2:buildVNodes
递归遍历栈生成的树:
- 文本节点 → 通过
renderTextNode渲染为<span style="white-space: pre-wrap"> - 标签节点 → 通过
renderTagNode查找componentMap,命中注册组件则渲染组件,否则使用DefaultTag - 子节点通过
default插槽传入父组件,实现嵌套渲染 reconstructRawHTML重建每个标签的原始 HTML 字符串作为block.content
对比
| Fast | Accurate | |
|---|---|---|
| 算法 | 正则单遍扫描 | 栈 + 递归遍历 |
| 嵌套标签 | 不支持 | 完全支持 |
| isClosed 准确性 | 有限(正则推断) | 可靠(栈状态) |
| 标签交错警告 | 无 | 有 |
| 结构化数据 (v-model:data) | 基本支持 | 完整支持 |
| 性能 | 快 | 略慢 |
选择建议
- 历史消息或纯展示场景 →
fast - 当前正在输出的流 →
accurate(推荐) - 涉及交互组件(表单、按钮等)→ 必须
accurate