一文吃透TinyRobot Bubble:从基础组件搭建完整AI消息渲染体系

一文吃透TinyRobot Bubble:从基础组件搭建完整 AI 消息渲染体系

在前端 AI 应用中,消息气泡(Bubble)是最核心的 UI 元素------它承载了从纯文本到 Markdown、从图片到工具调用的全部信息渲染。TinyRobot 的 Bubble 组件采用独特的"渲染器架构",提供了从基础气泡到复杂多模态消息的完整解决方案。

本文将从 Bubble 的基础用法入手,逐步深入到渲染器体系、状态管理、内容解析,带你搭建一套完整的 AI 消息渲染体系。


一、Bubble 基础:最小可用的消息气泡

1.1 最简示例

Bubble 的核心就是 content 属性------给它内容,它就能渲染:

vue 复制代码
<template>
  <tr-bubble
    content="TinyRobot 是一个专为 AI 应用设计的 Vue 3 组件库。"
    style="--tr-bubble-box-bg: var(--tr-color-primary-light)"
  />
</template>

<script setup lang="ts">
import { TrBubble } from '@opentiny/tiny-robot'
</script>

CSS 变量让你零成本自定义样式------背景色、字号、圆角、阴影等全部可控。

1.2 头像与位置

通过 avatarplacement 控制气泡的视觉归属:

vue 复制代码
<template>
  <tr-bubble content="AI 回复" :avatar="aiAvatar" placement="start" />
  <tr-bubble content="用户消息" :avatar="userAvatar" placement="end" />
</template>

<script setup lang="ts">
import { TrBubble } from '@opentiny/tiny-robot'
import { IconAi, IconUser } from '@opentiny/tiny-robot-svgs'
import { h } from 'vue'

const aiAvatar = h(IconAi, { style: { fontSize: '32px' } })
const userAvatar = h(IconUser, { style: { fontSize: '32px' } })
</script>
  • placement: 'start' --- 气泡靠左(AI 侧)
  • placement: 'end' --- 气泡靠右(用户侧)

1.3 气泡形状

shape 属性支持三种形状:

效果 适用场景
'corner'(默认) 对话泡泡形状,单侧有尖角 经典对话界面
'rounded' 四角等圆角 现代 UI 风格
'none' 无特殊圆角处理 自定义布局
vue 复制代码
<tr-bubble content="消息内容" shape="rounded" />

1.4 加载状态

loading 属性让气泡在 AI 思考时展示等待状态:

vue 复制代码
<tr-bubble :loading="true" />

二、内容渲染:从纯文本到多模态

2.1 Markdown 渲染

AI 回复中 Markdown 是标配。Bubble 内置了 Markdown 渲染器,只需安装依赖并配置:

bash 复制代码
pnpm add markdown-it dompurify
vue 复制代码
<template>
  <tr-bubble
    :content="mdContent"
    :fallback-content-renderer="BubbleRenderers.Markdown"
  />
</template>

<script setup lang="ts">
import { TrBubble, BubbleRenderers } from '@opentiny/tiny-robot'

const mdContent = '## 标题\n\n这是 **加粗** 和 `代码` 的混合内容'
</script>

注意:BubbleList 中使用 Markdown 渲染器,需要用 BubbleProvider 包裹。

2.2 流式文本

Bubble 的 content 属性是响应式的------动态修改它就能实现流式效果:

vue 复制代码
<template>
  <tr-bubble :content="streamContent" :avatar="aiAvatar" />
</template>

<script setup lang="ts">
import { ref } from 'vue'

const streamContent = ref('')

const startStream = async () => {
  streamContent.value = ''
  for (const char of '这是流式输出的文本内容。') {
    streamContent.value += char
    await new Promise(resolve => setTimeout(resolve, 100))
  }
}
</script>

搭配 useMessageresponseProvider,真正的 SSE 流式输出只需几行代码。

2.3 图片渲染

content 为数组且包含 type: 'image_url' 时,自动使用 Image 渲染器:

typescript 复制代码
const imageMessage = [
  { type: 'text', text: '这是一张图片:' },
  { type: 'image_url', image_url: { url: 'https://example.com/photo.jpg' } },
]

通过 contentRenderMode 控制图文渲染方式:

  • 'single'(默认):文本和图片在同一个 box 中
  • 'split':每个内容项单独一个 box
vue 复制代码
<tr-bubble :content="imageMessage" content-render-mode="split" />

2.4 内容渲染模式详解

contentRenderMode 是理解 Bubble 渲染的关键概念:

rust 复制代码
content = "纯文本"            → 单个 box
content = [{type:'text'...}]  → single模式:1个box / split模式:N个box
content = [{type:'text'...}, {type:'image_url'...}]  
  → single模式:1个box(图文混合)  
  → split模式:2个box(文字+图片各自独立)

三、插槽系统:定制气泡的每一个角落

Bubble 提供四个插槽,让你精准控制气泡结构:

插槽 位置 用途
prefix 气泡内容前 添加标签、时间戳等
suffix 气泡内容后 添加操作按钮等
content-footer 内容底部 添加引用来源等
after 气泡外部 添加反馈、评分等
vue 复制代码
<tr-bubble content="AI 回复">
  <template #prefix>
    <span class="label">AI助手</span>
  </template>
  <template #content-footer>
    <tr-feedback :actions="feedbackActions" />
  </template>
  <template #after>
    <span class="timestamp">刚刚</span>
  </template>
</tr-bubble>

四、完整 AI 对话渲染体系搭建

把上述能力组合起来,一个完整的 AI 对话界面就成型了:

vue 复制代码
<template>
  <tr-bubble-provider :fallback-content-renderer="BubbleRenderers.Markdown">
    <tr-bubble-list
      :messages="messages"
      :role-configs="roleConfigs"
      :auto-scroll="true"
    />
    <tr-sender
      v-model="inputText"
      :loading="isProcessing"
      @submit="handleSend"
      @cancel="handleCancel"
    />
  </tr-bubble-provider>
</template>

<script setup lang="ts">
import { ref, computed, h } from 'vue'
import { TrBubbleList, TrBubbleProvider, TrSender, BubbleRenderers } from '@opentiny/tiny-robot'
import { useMessage, sseStreamToGenerator } from '@opentiny/tiny-robot-kit'
import { IconAi, IconUser } from '@opentiny/tiny-robot-svgs'

const inputText = ref('')
const roleConfigs = {
  ai: { placement: 'start', avatar: h(IconAi, { style: { fontSize: '32px' } }) },
  user: { placement: 'end', avatar: h(IconUser, { style: { fontSize: '32px' } }) },
}

const { messages, sendMessage, requestState, abortRequest } = useMessage({
  responseProvider: async (body, signal) => {
    const res = await fetch('/api/chat', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(body),
      signal,
    })
    return sseStreamToGenerator(res, { signal })
  },
})

const isProcessing = computed(() => requestState.value === 'processing')
const handleSend = (text: string) => { inputText.value = ''; sendMessage(text) }
const handleCancel = () => abortRequest()
</script>

关键点:

  1. BubbleProvider 包裹 BubbleList,统一配置 Markdown 渲染器
  2. BubbleListroleConfigs 批量配置角色头像和位置
  3. useMessage 提供消息数据和流式引擎
  4. TrSender 负责输入和发送

这就是 TinyRobot 的"组件+Kit"双层架构带来的极致简洁------UI 层和数据层各司其职,组合即用。


五、CSS 变量速查

Bubble 提供了丰富的 CSS 变量用于样式定制:

气泡容器:

  • --tr-bubble-box-bg --- 背景色
  • --tr-bubble-box-padding --- 内边距
  • --tr-bubble-box-border-radius --- 圆角
  • --tr-bubble-max-width --- 最大宽度

文本:

  • --tr-bubble-text-color --- 文字颜色
  • --tr-bubble-text-font-size --- 字号
  • --tr-bubble-text-line-height --- 行高

图片:

  • --tr-bubble-image-max-width / --tr-bubble-image-max-height --- 图片尺寸限制

工具调用:

  • --tr-bubble-tool-call-bg --- 工具卡片背景色
  • --tr-bubble-tool-key-color --- JSON key 颜色

按角色定制样式也很方便------BubbleList 会为每个组添加 data-role 属性:

css 复制代码
[data-role='user'] {
  --tr-bubble-box-bg: var(--tr-color-primary-light);
}
[data-role='ai'] {
  --tr-bubble-box-bg: #f5f5f5;
}

六、总结

从最小可用的 tr-bubble 到完整的对话渲染体系,TinyRobot Bubble 的设计思路清晰:

  1. 单一职责:一个 Bubble 只渲染一条消息
  2. 渲染器架构:内容渲染与容器渲染完全可插拔
  3. 响应式驱动:content 变化即更新,天然适配流式场景
  4. CSS 变量定制:样式不侵入逻辑,零成本适配品牌风格

掌握了 Bubble 的基础组件能力,下一篇文章我们将深入 BubbleList,探索多轮对话、消息分组与滚动体验优化。


TinyRobot 官网https://opentiny/tiny-robot GitHub 仓库github.com/opentiny/ti...

相关推荐
英勇无比的消炎药1 小时前
深挖底层:TinyRobot Bubble消息气泡组件核心技术原理
vue.js
英勇无比的消炎药1 小时前
架构剖析:TinyRobot Bubble渲染器状态管理与工具调用机制
vue.js
英勇无比的消炎药1 小时前
多模态消息渲染实战:TinyRobot Bubble内容解析与contentResolver用法
vue.js
gg159357284602 小时前
Uni-app跨平台开发全解课程:从零基础到企业级多端落地实战
vue.js·uni-app
阿猫的故乡2 小时前
Vue + Axios 从入门到封装:拦截器、错误处理、请求取消、接口管理全搞定
前端·javascript·vue.js
秃头网友小李3 小时前
前端难点:Vue3 响应式遇上 Three.js / ECharts —— 为什么要用 shallowRef?
前端·vue.js
长空任鸟飞_阿康3 小时前
RAG 文档摄入全链路,从原理到生产落地
vue.js·人工智能·python
星空3 小时前
Node.js (Express) + Vue2 Axios 前后端交互 CRUD
vue.js·node.js·express
Hooray4 小时前
前端暗黑模式的适配艺术
前端·vue.js·视觉设计