Skip to content

标签拦截

<StreamContains> 的默认插槽中放入的组件会被自动注册为标签拦截器。

组件注册

vue
<StreamContains :model-value="text">
  <Think />
  <CodeBlock />
</StreamContains>

上述代码注册了两个拦截器:

  • <think> 映射到 Think 组件
  • <code-block> 映射到 CodeBlock 组件

命名规则

buildComponentMap 通过组件定义中的 name(或 __name)提取组件名,支持:

  • 大小写不敏感CodeBlockcode-blockcodeblock 都匹配 <code-block>
  • 递归扫描:会穿透 Fragment、嵌套数组、子 VNode 的 children
ts
// 内部 normalizeTagName 做 toLowerCase
// toKebabCase 将 PascalCase 转为 kebab-case

未注册标签

未匹配到组件的标签使用 DefaultTag 渲染:一个带标签名标头和灰底样式的容器。

子组件 Props

被拦截的组件自动注入以下 Props:

属性类型说明
blockStreamBlockData区块的完整结构化数据
attrsRecord<string, string | boolean>标签属性
contentstring标签内文本内容(随流式增长)
isClosedboolean标签是否已闭合
reportData(payload: unknown) => void回传数据至 block.payload

属性解析

parseTagAttrs 支持四种属性格式:

html
<code lang="ts" theme='dark' line=12 disabled />
<!--  双引号    单引号     无引号    布尔值  -->

解析结果:{ lang: 'ts', theme: 'dark', line: '12', disabled: true }

嵌套拦截

Accurate 模式下,嵌套标签会被递归解析:外层的 default 插槽中包含内层组件的渲染结果。

html
<card><think>思考过程</think></card>

若注册了 CardThinkThink 会出现在 Carddefault 插槽中。

Released under the MIT License.