Skip to content

StreamContains

核心容器组件,解析流式文本、拦截标签、分发渲染。

Props

参数类型默认值说明
model-value / v-modelstring''待解析的原始流式文本
mode'fast' | 'accurate''accurate'解析模式
data / v-model:dataStreamBlockData[][]结构化数据双向绑定
componentsRecord<string, Component>{}显式注册标签组件
base-componentComponent | nullnull统一包裹所有区块的组件

Events

事件参数说明
update:dataStreamBlockData[]结构化区块数据更新
parse-warningstringAccurate 模式检测到标签交错或孤立闭合标签时触发

子组件 Props

被拦截的组件接收以下 Props:

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

标签注册

默认插槽中的组件按 name__name 自动注册。

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

也可以通过 components 显式注册,适合组件来自自动导入、配置对象或不想渲染注册用插槽的场景。

vue
<script setup>
import { StreamContains, Think, Code } from '@huiol/stream-ui'

const components = {
  think: Think,
  code: Code
}
</script>

<template>
  <StreamContains :model-value="text" :components="components" />
</template>
  • 命名大小写不敏感:CodeBlock / code-block / codeblock 都匹配 <code-block>
  • 默认插槽和 components 会合并;同名时 components 显式注册优先
  • 未注册标签由 DefaultTag 降级渲染

StreamBlockData

ts
interface StreamBlockData {
  id: string
  tagName: string
  attrs?: Record<string, string | boolean>
  content: string
  isClosed: boolean
  category: 'component' | 'fallback' | 'text'
  payload?: unknown
}

标签上的字符串 id 属性会优先作为区块 ID,便于在 v-model:data 中稳定追踪 payload。

html
<input-block id="email" label="邮箱" />

baseComponent 插槽

插槽说明
default原始渲染结果(VNode)
raw区块的纯文本内容(字符串)
vue
<script setup>
const Base = defineComponent({
  setup(props, { slots }) {
    return () => h('div', [
      slots.default?.(),           // 渲染结果
      h('pre', slots.raw?.())      // 原始文本
    ])
  }
})
</script>

注意事项

  • v-model:data 更新合并到 queueMicrotask 中执行,避免高频重复触发
  • 相同文本的重复渲染会跳过 emit(areBlocksEqual 对比)
  • Accurate 模式下的解析警告会触发 parse-warning,并同时在 console.groupCollapsed 中输出

Released under the MIT License.