TinyRobot AI 对话组件库全组件使用指南

TinyRobot 全组件使用指南:打造你的 AI 聊天界面,一次搞定!

还在为 AI 聊天界面手搓 DOM 发愁?还在纠结消息气泡怎么排版、输入框怎么搞联想?别慌,TinyRobot 来拯救你了!这套面向 Vue 的 AI 聊天组件库,16 个组件覆盖从"你好"到"再见"的全流程,让你的聊天界面从零到一,比泡面还快。

本文将逐一拆解 TinyRobot 的每一个组件------从最常用的 Bubble、Sender,到冷门但好用的 DragOverlay、McpServerPicker------帮你快速上手,少踩坑,多摸鱼。


一、Bubble 气泡组件 ------ 消息的灵魂容器

如果你要做一个聊天界面,Bubble 就是你的第一个组件。它负责渲染每一条消息------不管是文字、图片、Markdown 还是 AI 的推理过程,都由 Bubble 承包。

核心能力

  • 消息展示:文本、图片、Markdown 等多种内容类型一站式渲染
  • 流式输出content 是响应式的,动态赋值就能实现打字机效果
  • 消息分组:连续相同角色的消息自动合并,告别"一条一条往下滚"的尴尬
  • 自定义渲染器:Box 渲染器控制气泡样式布局,Content 渲染器控制内容展示,想怎么画就怎么画
  • 状态管理 :通过 state 属性存储 UI 数据,点赞、展开收起全靠它

快速上手

vue 复制代码
<template>
  <tr-bubble content="你好,我是 AI 助手!" placement="start" />
</template>

就这么简单,一个气泡出来了。

头像和位置

vue 复制代码
<tr-bubble
  content="我来回答你的问题"
  :avatar="CustomAvatar"
  placement="end"
/>

placement 支持 start(靠左)和 end(靠右),avatar 支持自定义 Vue 节点或组件。

气泡形状

通过 shape 属性设置气泡形状,支持三种风格:

  • corner(默认):经典聊天气泡,带小尖角
  • rounded:圆角矩形,现代感满满
  • none:无圆角,适合极简风格
vue 复制代码
<tr-bubble content="圆角风格" shape="rounded" />

流式文本 ------ AI 回答的打字机效果

content 是响应式的!你只需要动态更新 content,气泡就会自动跟着变:

vue 复制代码
<script setup>
import { ref } from 'vue'
const content = ref('')
// 模拟流式输出
setTimeout(() => { content.value = '正在思考...' }, 500)
setTimeout(() => { content.value = '答案是:42' }, 1500)
</script>

<template>
  <tr-bubble :content="content" placement="end" />
</template>

Markdown 渲染

需要先安装依赖:

bash 复制代码
npm install markdown-it dompurify

然后通过 fallbackContentRenderer 设置 Markdown 渲染器:

vue 复制代码
<template>
  <tr-bubble
    :content="mdContent"
    :fallback-content-renderer="BubbleRenderers.Markdown"
  />
</template>

<script setup>
import { BubbleRenderers } from '@opentiny/tiny-robot'
</script>

渲染器系统 ------ 想怎么画就怎么画

Bubble 的渲染器架构分两层:

  • Box 渲染器:渲染气泡外层容器(样式、布局)
  • Content 渲染器:渲染气泡内容(文本、图片、Markdown 等)

渲染器通过 find 函数匹配,优先级由 priority 控制,数值越小越优先。内置渲染器包括:

  • BubbleRenderers.Text:默认文本渲染
  • BubbleRenderers.Markdown:Markdown 渲染
  • BubbleRenderers.Image:图片渲染
  • BubbleRenderers.Loading:加载状态
  • BubbleRenderers.Reasoning:推理内容(AI 思考过程)
  • BubbleRenderers.Tool:工具调用

自定义渲染器也很简单------写个 Vue 组件,用 markRaw 包装,配置匹配规则即可:

vue 复制代码
<script setup lang="ts">
import type { BubbleContentRendererProps } from '@opentiny/tiny-robot'

defineProps<BubbleContentRendererProps>()
</script>

<template>
  <div class="custom-content">{{ message.content }}</div>
</template>

BubbleList ------ 消息列表

BubbleList 是消息列表组件,负责批量渲染消息并管理分组。

vue 复制代码
<template>
  <tr-bubble-list :messages="messages" :role-configs="roleConfigs" :auto-scroll="true" />
</template>

关键 Props:

属性 说明
messages 消息数组(必填)
groupStrategy 分组策略:consecutive(连续合并)或 divider(按分割角色分组)
roleConfigs 各角色默认配置(头像、位置、形状等)
autoScroll 是否自动滚动到底部

样式定制

Bubble 提供了大量 CSS 变量,从背景色到圆角,从字号到阴影,一应俱全:

css 复制代码
:root {
  --tr-bubble-box-bg: #f0f0f0;          /* 气泡背景色 */
  --tr-bubble-text-font-size: 14px;      /* 文字大小 */
  --tr-bubble-box-shape-rounded-radius: 12px; /* 圆角 */
}

二、Sender 消息输入框 ------ 用户打字的终极武器

Sender 是 TinyRobot 中最复杂也最强大的组件------一个高度可组合的聊天输入框,支持文本输入、自动联想、@提及、模板填充、语音输入、文件上传,基本上你能想到的输入交互方式它都覆盖了。

输入模式

支持 single(单行)和 multiple(多行)两种模式。单行模式下内容超宽时自动切换为多行:

vue 复制代码
<tr-sender v-model="text" mode="single" />

状态控制

vue 复制代码
<tr-sender v-model="text" :loading="isLoading" :disabled="isDisabled" />

加载状态下点击停止按钮会触发 cancel 事件,方便取消 AI 响应。

提交方式

三种快捷键方案,总有一款适合你:

  • submitType="enter":Enter 提交,Ctrl+Enter/Shift+Enter 换行
  • submitType="ctrlEnter":Ctrl+Enter 提交,Enter 换行
  • submitType="shiftEnter":Shift+Enter 提交,Enter 换行

扩展系统 ------ Sender 的灵魂

v0.4 的 Sender 用 extensions prop 实现可插拔功能扩展,所有扩展都支持响应式数据自动同步。

模板填充(Template)

typescript 复制代码
import { TrSender } from '@opentiny/tiny-robot'

const extensions = [TrSender.template(templates)]
// 或标准配置
const extensions = [TrSender.Template.configure({ items: templateData })]

模板数据变化时自动更新编辑器内容,光标自动聚焦到第一个可编辑字段。

提及功能(Mention)

typescript 复制代码
const extensions = [TrSender.mention(mentions, '@')]
// 支持自定义触发字符
const extensions = [TrSender.mention(mentions, '#')]

输入触发字符(默认 @)弹出选择列表,支持键盘导航和搜索过滤。

智能联想(Suggestion)

typescript 复制代码
// 不过滤,直接显示所有建议
const extensions = [TrSender.suggestion(suggestions)]

// 自定义过滤
const extensions = [TrSender.suggestion(suggestions, { filterFn: customFilter })]

支持三种高亮模式:自动匹配、精确指定、自定义函数。选中建议项时还有灰色补全提示,按 Tab 一键应用。

语音输入

通过独立的 VoiceButton 组件实现:

vue 复制代码
<template>
  <tr-sender>
    <template #footer>
      <voice-button
        :speech-config="{ lang: 'zh-CN', continuous: true }"
        @speech-start="onStart"
        @speech-final="onFinal"
      />
    </template>
  </tr-sender>
</template>

支持浏览器内置语音识别和第三方语音服务(阿里云、百度等),还可以自定义录音 UI(比如移动端的"按住说话")。

文件上传

通过 UploadButton 组件实现:

vue 复制代码
<template>
  <tr-sender>
    <template #footer>
      <upload-button accept="image/*" :multiple="true" @select="onFilesSelected" />
    </template>
  </tr-sender>
</template>

支持文件类型过滤、大小限制和数量限制。

自定义插槽

Sender 提供了 headerprefixfooterfooter-rightcontentactions-inline 等多个插槽,其中 footerfooter-right 插槽提供了 editorhasContentdisabledloading 等状态数据以及 focusinsertappendreplace 等操作方法,功能按钮随你定制。

字数限制

vue 复制代码
<tr-sender v-model="text" :max-length="500" :show-word-limit="true" />

超出限制时红色标示,且无法提交。

样式定制

CSS 变量丰富到可以调出任何风格:

css 复制代码
.my-sender {
  --tr-sender-bg-color: #f5f5f5;
  --tr-sender-text-color: #333;
  --tr-sender-button-size: 40px;
}

三、Container 容器 ------ 聊天窗口的骨架

Container 是聊天窗口的"外框",提供标题栏、内容区域和底部操作栏,支持全屏和窗口两种模式。

vue 复制代码
<template>
  <tr-container v-model:show="visible" v-model:fullscreen="isFullscreen" title="AI 助手">
    <template #default>
      <!-- 聊天内容 -->
    </template>
    <template #footer>
      <!-- 输入区域 -->
    </template>
  </tr-container>
</template>

全屏模式下自动加上 fullscreen 类名,可以用 .fullscreen 选择器自定义样式。

属性 说明
v-model:show 是否显示容器
v-model:fullscreen 是否全屏
title 容器标题(默认 'OpenTiny NEXT'

插槽有 default(主体内容)、title(自定义标题区域)、operations(标题栏右侧操作区)、footer(底部操作栏)。


四、Prompts 提示集 ------ 引导用户的第一步

Prompts 是展示提示列表的组件,常用于聊天界面的欢迎页面,引导用户点击预设问题开始对话。

vue 复制代码
<template>
  <tr-prompts
    :items="promptItems"
    @item-click="onItemClick"
  />
</template>

<script setup>
const promptItems = [
  { label: '帮我写代码', description: '根据描述生成代码片段', icon: CodeIcon },
  { label: '翻译文档', description: '支持多语言互译', badge: '热门' },
]
</script>

关键特性:

  • 三种尺寸smallmedium(默认)、large
  • 徽章badge 属性给提示项右上角加标签
  • 纵向展示vertical 属性切换为垂直排列
  • 自动换行wrap 属性让提示项超出宽度时自动折行
  • 响应式布局 :配合 wrap + item-style 实现自适应
  • 禁用状态disabled 属性灰掉提示项

五、Welcome 欢迎组件 ------ 聊天界面的第一印象

Welcome 组件展示欢迎信息,包含标题、描述和图标,常用于新对话的起始页面。

vue 复制代码
<template>
  <tr-welcome
    title="你好,我是 AI 助手"
    description="有任何问题都可以问我"
    align="center"
  >
    <template #footer>
      <tr-prompts :items="promptItems" />
    </template>
  </tr-welcome>
</template>

align 支持 leftcenter(默认)、right 三种对齐方式。icon 支持自定义 Vue 节点或 JSX。footer 插槽用来放提示列表等内容。


六、Attachments 附件卡片 ------ 文件也能聊

Attachments 组件展示文件列表,支持图片预览、文件下载、状态显示,让聊天界面也能处理文件。

展示形式

  • auto(默认):自动检测------全是图片就用图片墙,否则用文件卡片
  • picture:强制图片墙
  • card:强制文件卡片

文件状态

  • success:上传成功,显示文件大小等元信息
  • uploading:上传中,显示加载动画
  • error:上传失败,显示错误信息和"重试"按钮
vue 复制代码
<template>
  <tr-attachments v-model:items="files" variant="auto" />
</template>

自定义操作按钮

typescript 复制代码
const actions = [
  { type: 'preview', label: '预览' },
  { type: 'download', label: '下载' },
  { type: 'custom', label: '分享', handler: (file) => shareFile(file) }
]

内置 7 种文件类型识别(image、pdf、word、excel、ppt、folder、other),可以通过 fileMatchers 扩展自定义类型,通过 fileIcons 替换默认图标。


七、Feedback 气泡反馈 ------ 让用户"有话可说"

Feedback 组件附加在消息气泡下方,提供操作按钮、动作按钮和数据来源,让 AI 回答不只是"看",还能"交互"。

vue 复制代码
<template>
  <tr-feedback
    :operations="[{ name: 'explain', label: '解释更多' }]"
    :actions="[{ name: 'like', label: '有帮助', icon: 'like' }]"
    :sources="[{ label: '官方文档', link: 'https://...' }]"
  />
</template>

内置支持的 action 图标:copyrefreshlikedislike。也可以传入自定义图标。

operationsLimitactionsLimitsourcesLinesLimit 控制默认显示数量,超出的自动折叠。


八、History 历史记录 ------ 对话也能翻历史

History 组件展示对话历史列表,支持分组、重命名、删除、自定义菜单项等操作。

vue 复制代码
<template>
  <tr-history :data="historyData" :selected="selectedId" @item-click="onItemClick" />
</template>

数据支持两种格式:

  • 直接数组:HistoryItem[]
  • 分组数组:HistoryGroup[]
typescript 复制代码
// 分组格式
const historyData = [
  { group: '今天', items: [{ id: '1', title: '帮我写代码' }] },
  { group: '昨天', items: [{ id: '2', title: '翻译文档' }] }
]

支持自定义菜单项(默认提供重命名和删除),支持 item-prefixitem-title 两个插槽自定义显示。


九、SuggestionPills 建议按钮组 ------ 横向建议条

SuggestionPills 是一个横向排列的建议按钮组,适合在输入框上方或聊天界面的快捷操作区域使用。

vue 复制代码
<template>
  <tr-suggestion-pills>
    <tr-suggestion-pill-button :item="{ text: '写代码', icon: CodeIcon }" />
    <tr-suggestion-pill-button :item="{ text: '翻译' }" />
  </tr-suggestion-pills>
</template>

关键特性:

  • overflowMode:多余项的处理方式------expand(展开显示)或 scroll(横向滚动)
  • showAllButtonOn:显示"更多"按钮的时机------hover(默认)或 always
  • 每个药丸项必须包含 texticon 至少一个

十、SuggestionPopover 建议弹出框 ------ 弹出式建议列表

SuggestionPopover 是弹出式的建议列表组件,支持分组数据、自定义渲染、加载状态和移动端适配。

vue 复制代码
<template>
  <tr-suggestion-popover
    :data="suggestionData"
    title="智能建议"
    trigger="click"
    @item-click="onItemClick"
  />
template>

触发方式支持 click(点击触发)和 manual(手动控制显示状态)。

数据支持普通项和分组项两种格式,分组项加 group 字段即可。提供了 triggeritemloadingemptyheaderbody 六个插槽,灵活度极高。


十一、DropdownMenu 下拉菜单 ------ 轻量级菜单

DropdownMenu 是一个轻量级下拉菜单组件,目前主要服务于 SuggestionPills 的"更多"操作。

vue 复制代码
<template>
  <tr-dropdown-menu :items="menuItems" trigger="click">
    <template #trigger>
      <button>更多操作</button>
    </template>
  </tr-dropdown-menu>
</template>

支持三种触发方式:clickhovermanualshow 属性在 click/hover 模式下支持双向绑定,manual 模式下仅单向绑定。


十二、DragOverlay 拖拽浮层 ------ 拖文件进来的视觉提示

DragOverlay 提供拖拽上传的视觉反馈,由 v-dropzone 指令和 <tr-drag-overlay> 组件协同工作。

vue 复制代码
<template>
  <div v-dropzone="dropzoneOptions">
    <!-- 你的聊天窗口 -->
  </div>
  <tr-drag-overlay :is-dragging="isDragging" overlay-title="拖拽文件到这里" />
</template>

<script setup>
const isDragging = ref(false)
const dropzoneOptions = {
  onDrop: (files) => handleFiles(files),
  onError: (rejection) => console.error(rejection),
  onDraggingChange: (dragging) => { isDragging.value = dragging },
  accept: '.png,.jpg',
  maxSize: 10485760,  // 10MB
  maxFiles: 3
}
</script>

支持自定义浮层内容(通过 overlay 插槽)、全屏模式、禁用状态。文件被拒绝时会触发 onError,告诉你具体原因(文件类型不符、超大小、超数量等)。


十三、Theme 主题 ------ 一键换肤,支持暗黑模式

ThemeProvider 是主题管理组件,通过 CSS 变量实现主题和暗黑/亮色模式切换。

vue 复制代码
<template>
  <tr-theme-provider color-mode="dark" theme="custom-theme">
    <!-- 你的聊天界面 -->
  </tr-theme-provider>
</template>

颜色模式

  • light:亮色
  • dark:暗色
  • auto(默认):跟随系统

自定义主题 CSS

css 复制代码
[data-tr-theme='custom-theme'][data-tr-color-mode='dark'] {
  --tr-bubble-box-bg: #2a2a2a;
  --tr-sender-bg-color: #1e1e1e;
}

useTheme 组合式函数

typescript 复制代码
const { toggleColorMode, setColorMode, setTheme } = useTheme()
toggleColorMode()  // 切换亮/暗
setColorMode('dark')  // 设置暗色模式
setTheme('custom-theme')  // 切换自定义主题

支持嵌套主题、主题数据持久化(通过 storagestorageKey 属性),刷新页面自动恢复。


十四、SenderCompat ------ v0.3 的老朋友,升级过渡的好帮手

如果你是从 v0.3.x 升级过来的用户,SenderCompat 就是你的过渡桥梁------保留了大部分 v0.3 的 API,底层用 v0.4 实现,改动最小。

typescript 复制代码
// 只改一行导入
import { TrSenderCompat as TrSender } from '@opentiny/tiny-robot'

需要处理的 5 个破坏性变更:

  1. 紧凑模式:class="tr-sender-compact"size="small"
  2. 装饰内容插槽:#decorativeContent#content + disabled
  3. 模板数据设置:新增 setTemplateData() 便捷方法
  4. 插槽名变更:#actions#actions-inline#footer-left#footer
  5. 移除不必要的 key 绑定

最终迁移路径:v0.3 Sender → SenderCompat → v0.4 Sender


十五、McpAddForm 插件添加表单 ------ MCP 插件的入口

McpAddForm 是添加 MCP 插件的表单组件,支持表单添加和代码添加两种方式。

vue 复制代码
<template>
  <tr-mcp-add-form
    :add-type="addType"
    :form-data="formData"
    @confirm="onConfirm"
    @cancel="onCancel"
  />
</template>

表单数据结构:

typescript 复制代码
interface McpAddFormData {
  name: string
  description: string
  type: 'sse' | 'streamableHttp'
  url: string
  headers: string
  thumbnail?: File | null
}

addType 支持 form(表单模式)和 code(代码模式),两种方式自由切换。


十六、McpServerPicker 插件选择器 ------ MCP 插件管理中心

McpServerPicker 是 MCP 插件的全生命周期管理组件,支持已安装插件和市场插件两个标签页。

vue 复制代码
<template>
  <tr-mcp-server-picker
    :installed-plugins="installedList"
    :market-plugins="marketList"
    v-model:visible="pickerVisible"
    v-model:active-count="activeCount"
    @plugin-add="onPluginAdd"
    @plugin-toggle="onPluginToggle"
  />
</template>

核心功能

  • 双标签页:已安装插件 + 市场插件
  • 搜索和分类筛选:内置搜索框,市场还支持分类筛选
  • 插件状态管理:启用/禁用插件和工具
  • 添加状态控制idle(未添加)→ loading(添加中)→ added(已添加)
  • 两种弹出方式fixed(固定定位)和 drawer(抽屉),通过 popupConfig 配置
typescript 复制代码
// 添加状态控制示例
const handlePluginAdd = (plugin) => {
  targetPlugin.addState = 'loading'  // 显示添加中
  addPluginToServer(plugin)
    .then(() => { targetPlugin.addState = 'added' })
    .catch(() => { targetPlugin.addState = 'idle' })  // 失败重置
}

完整组合示例:打造一个全功能聊天界面

最后,让我们把所有组件组合起来,打造一个完整的 AI 聊天界面:

vue 复制代码
<template>
  <tr-theme-provider color-mode="auto">
    <tr-container v-model:show="visible" v-model:fullscreen="fullscreen" title="AI 助手">
      <template #default>
        <!-- 欢迎页面 -->
        <tr-welcome v-if="!messages.length" title="你好" description="有问题尽管问">
          <template #footer>
            <tr-prompts :items="prompts" @item-click="onPromptClick" />
          </template>
        </tr-welcome>

        <!-- 消息列表 -->
        <tr-bubble-list
          v-else
          :messages="messages"
          :role-configs="roleConfigs"
          :auto-scroll="true"
        >
          <template #suffix="{ messages }">
            <tr-feedback
              :actions="[{ name: 'like', icon: 'like' }, { name: 'copy', icon: 'copy' }]"
              :sources="sources"
            />
          </template>
        </tr-bubble-list>
      </template>

      <template #footer>
        <div v-dropzone="dropzoneOptions">
          <tr-sender
            v-model="inputText"
            :loading="isLoading"
            :extensions="extensions"
            @submit="onSubmit"
            @cancel="onCancel"
          >
            <template #footer>
              <upload-button @select="onFilesSelected" />
              <voice-button :speech-config="{ lang: 'zh-CN' }" />
            </template>
          </tr-sender>
        </div>
        <tr-drag-overlay :is-dragging="isDragging" overlay-title="拖拽文件到聊天" />
      </template>

      <template #operations>
        <tr-suggestion-pills>
          <tr-suggestion-pill-button :item="{ text: '代码', icon: CodeIcon }" />
          <tr-suggestion-pill-button :item="{ text: '翻译' }" />
        </tr-suggestion-pills>
      </template>
    </tr-container>
  </tr-theme-provider>
</template>

总结

TinyRobot 的 16 个组件,从消息展示(Bubble)到用户输入(Sender),从窗口容器(Container)到主题管理(Theme),从文件处理(Attachments、DragOverlay)到 MCP 插件管理(McpServerPicker、McpAddForm),覆盖了 AI 聊天界面的方方面面。

组件速查表

组件 定位
Bubble / BubbleList 消息气泡与列表
Sender 消息输入框(含扩展系统)
SenderCompat v0.3 升级过渡组件
Container 聊天窗口容器
Prompts 提示集(预设问题列表)
Welcome 欢迎信息展示
Attachments 附件卡片(文件/图片列表)
Feedback 消息反馈(点赞、复制、来源)
History 对话历史记录
SuggestionPills 横向建议按钮组
SuggestionPopover 弹出式建议列表
DropdownMenu 下拉菜单
DragOverlay 拖拽上传浮层
ThemeProvider / useTheme 主题与暗黑模式
McpAddForm MCP 插件添加表单
McpServerPicker MCP 插件选择器

用这套组件库,一个完整的 AI 聊天界面,从开发到上线,可能比你泡一杯咖啡的时间还短(当然,调试除外 😄)。


OpenTiny NEXT 是一套企业智能前端开发解决方案,以生成式 UI 和 WebMCP 两大核心技术为基础,对现有传统的 TinyVue 组件库、TinyEngine 低代码引擎等产品进行智能化升级,构建出面向 Agent 应用的前端 NEXT-SDKs、AI Extension、TinyRobot智能助手、GenUI等新产品,加速企业应用的智能化改造,实现AI理解用户意图自主完成任务。

欢迎加入 OpenTiny 开源社区。添加微信小助手:opentiny-official 一起参与交流前端技术~

OpenTiny 官网:opentiny.design/

TinyRobot 代码仓库:github.com/opentiny/ti... (欢迎star ⭐)

TinyRobot skill源码:github.com/opentiny/ag... (欢迎 Star ⭐)

相关推荐
前端Hardy1 小时前
GitHub 爆火!Three.js + React + ECharts 打造最强数据大屏
前端·javascript
lichenyang4531 小时前
ArkTS 资源与暗色模式:为什么我手机切暗色,App 内容区却不变
前端
老王以为1 小时前
Claude Code 的产品哲学:当价值观成为架构
前端·claude·vibecoding
程序员黑豆1 小时前
AI全栈开发 - Java:变量
java·前端·ai编程
tedcloud1231 小时前
HyperFrames部署教程:用HTML生成MP4视频
前端·数据库·人工智能·html·音视频
江米小枣tonylua2 小时前
真多线程!Bun作者要给JS大手术
前端
如果超人不会飞2 小时前
Vue.js
vue.js