Skip to content

流式渲染模式

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,不入栈
  • 流式处理:未闭合的标签保留在栈中,isClosedfalse

阶段 2:buildVNodes

递归遍历栈生成的树:

  • 文本节点 → 通过 renderTextNode 渲染为 <span style="white-space: pre-wrap">
  • 标签节点 → 通过 renderTagNode 查找 componentMap,命中注册组件则渲染组件,否则使用 DefaultTag
  • 子节点通过 default 插槽传入父组件,实现嵌套渲染
  • reconstructRawHTML 重建每个标签的原始 HTML 字符串作为 block.content

对比

FastAccurate
算法正则单遍扫描栈 + 递归遍历
嵌套标签不支持完全支持
isClosed 准确性有限(正则推断)可靠(栈状态)
标签交错警告
结构化数据 (v-model:data)基本支持完整支持
性能略慢

选择建议

  • 历史消息或纯展示场景 → fast
  • 当前正在输出的流 → accurate(推荐)
  • 涉及交互组件(表单、按钮等)→ 必须 accurate

Released under the MIT License.