新手必看玩转TinyRobot一定要避开这些坑

新手必看10个常见坑,每个都有症状根因和修复方案# 新手必看!玩转 TinyRobot 一定要避开这些坑

刚上手 TinyRobot,满怀信心写了个 AI 对话页面,结果------组件渲染了但样式炸了、事件怎么都触发不了、主题切换一脸懵?别慌,这篇文章把新手最容易踩的 10 个坑整理出来,每个都有真实症状、根因分析和修复方案,看完直接少走一半弯路。

坑 1:忘记引入样式------组件能渲染但丑到离谱

症状: 页面上能看到 tr-bubbletr-sender 的结构,但排版混乱,没有背景色、圆角、间距,像是裸奔的 HTML。

原因: TinyRobot 的组件逻辑和样式是分离打包的。你只引入了 JS,没引入 CSS,组件虽然注册成功,但所有 --tr-* CSS 变量和样式规则都没加载。

修复:main.ts 中加上样式导入,这一步不管是按需引入还是全局引入都不能省

ts 复制代码
import { createApp } from 'vue'
import App from './App.vue'
import '@opentiny/tiny-robot/dist/style.css' // 必须引入!

const app = createApp(App)
app.mount('#app')

小提示:如果你用 Vite,确认 optimizeDeps 没把 @opentiny/tiny-robot/dist/style.css 排除在外。某些 CDN 引入方式也会漏掉样式,优先用 npm 包管理。

坑 2:组件名写错------用 Bubble 而不是 TrBubble

症状: 模板里写了 <Bubble><Sender>,Vue 提示组件未注册,页面什么都不显示。

原因: TinyRobot 所有组件都以 Tr 前缀注册(TinyRobot 缩写)。按需引入时导入名是 TrBubbleTrSender,模板里对应的标签是 <tr-bubble>tr-sender>,不是 <Bubble>

修复:

vue 复制代码
<!-- 错误 -->
<template>
  <Bubble content="你好" role="ai" />
</template>

<script setup>
import { Bubble } from '@opentiny/tiny-robot' // ❌ 不存在这个导出
</script>

<!-- 正确 -->
<template>
  <tr-bubble content="你好" role="ai" />
</template>

<script setup>
import { TrBubble } from '@opentiny/tiny-robot' // ✅ Tr 前缀
</script>

完整对应关系:TrBubble<tr-bubble>TrSender<tr-sender>TrContainer<tr-container>ThemeProvider<theme-provider>(注意 ThemeProvider 没有 Tr 前缀)。

坑 3:全局引入和按需引入混用------组件重复注册

症状: 控制台出现 Vue 的组件重复注册警告,某些组件行为异常,或者打包体积明显偏大。

原因: 你在 main.ts 里用 app.use(TinyRobot) 全局注册了所有组件,然后在页面里又 import { TrBubble } from '@opentiny/tiny-robot' 按需引入。两套注册撞车了。

修复: 选一种方式,别混着用:

ts 复制代码
// 方案 A:纯全局引入(适合快速原型)
import TinyRobot from '@opentiny/tiny-robot'
import '@opentiny/tiny-robot/dist/style.css'
app.use(TinyRobot) // 全局注册,页面里不用再 import

// 方案 B:纯按需引入(推荐,体积更小)
// main.ts 只引样式,不 app.use
import '@opentiny/tiny-robot/dist/style.css'
// 页面里按需 import
import { TrBubble, TrSender } from '@opentiny/tiny-robot'

经验之谈:哪怕你只用了 2-3 个组件,全局引入也会把所有组件打进 bundle。按需引入配合 Tree Shaking 才是正解。

坑 4:Node.js 版本过低------构建悄无声息地失败

症状: pnpm installpnpm build 报一堆奇怪的错误,比如 ERR_MODULE_NOT_FOUND、语法解析失败,或者依赖安装成功但运行时白屏。

原因: TinyRobot 依赖了较新的 JavaScript 特性(如 using 声明、Symbol.asyncDispose 等),要求 Node.js >= 20.13.0。如果你还在用 Node 16 或 18,构建工具会在解析阶段就出错,而且错误信息往往不太直观。

修复:

bash 复制代码
# 检查当前版本
node -v

# 如果低于 20.13.0,升级 Node
# 推荐用 nvm 管理版本
nvm install 20
nvm use 20

别忘了升级后重新 pnpm install,锁文件可能需要重新生成。

坑 5:没用 ThemeProvider 包裹------主题切换永远不生效

症状: 调了 setColorMode('dark'),页面一点变化都没有,CSS 变量值始终是亮色模式。

原因: TinyRobot 的主题系统基于 ThemeProvider 组件注入,它会在目标元素上添加 data-tr-themedata-tr-color-mode 属性。如果你的应用没有被 ThemeProvider 包裹,useTheme() 返回 false,主题切换当然无效。

修复:

vue 复制代码
<!-- 错误:直接用 useTheme -->
<template>
  <App />
</template>

<script setup>
import { useTheme } from '@opentiny/tiny-robot'
const { setColorMode } = useTheme() // ❌ 返回 false,不在 Provider 内
</script>

<!-- 正确:先包裹 ThemeProvider -->
<template>
  <ThemeProvider v-model:color-mode="colorMode">
    <App />
  </ThemeProvider>
</template>

<script setup>
import { ThemeProvider, useTheme } from '@opentiny/tiny-robot'
const colorMode = ref('auto')

// App 组件内部可以用 useTheme
// const { setColorMode, toggleColorMode } = useTheme()
</script>

记住:useTheme() 必须在 ThemeProvider 包裹的子组件中调用,不能在外层或同级使用。

坑 6:useMessage 用在了错误的作用域

症状: sendMessage 调用后没反应,messages 不更新,或者报 Cannot read properties of undefined 之类的错误。

原因: useMessage 本身不依赖 ThemeProvider,但常见的错误是在 setup 之外调用它(比如在普通函数或 setTimeout 里),导致响应式上下文丢失。另一个常见问题是把 useMessage 的返回值当普通对象解构,丢失了响应性。

修复:

vue 复制代码
<script setup>
import { useMessage } from '@opentiny/tiny-robot-kit'

// ✅ 在 setup 中直接调用,返回值保持响应式
const { messages, sendMessage, requestState } = useMessage({
  responseProvider: myProvider,
})

// ❌ 不要在非 setup 上下文中调用
// setTimeout(() => {
//   const { messages } = useMessage({ ... }) // 响应式丢失
// }, 1000)
</script>

如果需要在不同组件间共享 useMessage 的状态,把返回值通过 provide/inject 或 props 传递,而不是重新调用 useMessage

坑 7:v0.3.x 代码直接搬到 v0.4.0------大面积报错

症状: 从 v0.3.x 升级到 v0.4.0 后,项目编译报错:client 不存在、AIClient 已废弃、Sender 的 allowSpeech/buttonGroup 等属性没了、事件名变了。

原因: v0.4.0 是一次重大升级(Breaking Changes),核心变更包括:

  • useMessageclient 参数改为 responseProvider
  • AIClient 标记为废弃,要用 useMessage + responseProvider 代替
  • Sender 组件整体重构,allowSpeechbuttonGroupthemesuggestions 等旧 props 全部移除
  • 多个旧事件名被替换

修复(快速迁移方案): 使用 SenderCompat 做过渡:

ts 复制代码
// ❌ v0.3.x 旧代码
import { TrSender } from '@opentiny/tiny-robot'

// ✅ 快速迁移:改一行导入即可
import { TrSenderCompat as TrSender } from '@opentiny/tiny-robot'

SenderCompat 保留了 v0.3.x 大部分 API,只需处理 5 个破坏性变更(紧凑模式用 size="small" 代替 class、插槽名变更等)。详细迁移步骤参考官方文档。

修复(useMessage 迁移):

ts 复制代码
// ❌ v0.3.x:使用 client
const { messages } = useMessage({
  client: new AIClient({ ... }),
})

// ✅ v0.4.0:使用 responseProvider
const { messages } = useMessage({
  responseProvider: async (requestBody, abortSignal) => {
    const response = await fetch('/api/chat', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(requestBody),
      signal: abortSignal,
    })
    return sseStreamToGenerator(response)
  },
})

新项目直接用 v0.4.0 API,别回头找 v0.3.x 的用法。旧项目可以先 SenderCompat 过渡,再逐步迁移到新 Sender。

坑 8:SSE 流处理不对------responseProvider 没用 sseStreamToGenerator

症状: AI 对话发送后,消息列表只出现一条空的 assistant 消息,内容始终不更新;或者后端返回了数据但前端只显示了最后一个 chunk。

原因: responseProvider 的返回值决定了响应模式。返回 Promise<T> 时是一次性结果;返回 AsyncGenerator<T> 时才能逐块消费、增量合并。如果你把 SSE 流的 Response 直接当作 Promise 返回,useMessage 不知道怎么逐块处理它。

修复:sseStreamToGenerator 把 fetch Response 转为 AsyncGenerator:

ts 复制代码
import { sseStreamToGenerator } from '@opentiny/tiny-robot-kit'

const { messages, sendMessage } = useMessage({
  responseProvider: async (requestBody, abortSignal) => {
    const response = await fetch('/api/chat/completions', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(requestBody),
      signal: abortSignal,
    })

    // ✅ 关键:用 sseStreamToGenerator 转换 SSE 流
    return sseStreamToGenerator(response, { signal: abortSignal })
  },
})

如果你的后端不支持 SSE(返回完整 JSON),直接返回 Promise<ChatCompletion> 即可,不需要 sseStreamToGenerator。

坑 9:无视 Tree Shaking------全局引入导致 bundle 臃肿

症状: 打包后产物体积异常大,首屏加载慢,Lighthouse 性能分数低。

原因: 你用了全局引入 app.use(TinyRobot),所有组件(Bubble、Sender、Container、History、McpServerPicker......十几个组件全量打包)都被打进 bundle,哪怕你只用了 TrBubble 和 TrSender 两个。

修复: 只引你需要的:

vue 复制代码
<!-- 只用 2-3 个组件的场景 -->
<script setup>
import { TrBubble, TrSender } from '@opentiny/tiny-robot'
import { useMessage } from '@opentiny/tiny-robot-kit'
</script>
ts 复制代码
// main.ts 只引样式,不 app.use
import '@opentiny/tiny-robot/dist/style.css'

这样 Vite/Rollup 的 Tree Shaking 会自动剔除没用到的组件,bundle 体积能缩减 60% 以上。

简单判断:如果你的项目里 <tr-*> 标签不超过 5 种,就用按需引入。只有确实用了大部分组件的场景才考虑全局引入。

坑 10:事件名搞错------submit 还是 onSubmit?

症状: 你在模板里写了 @onSubmit@on-send,发送消息后回调完全不触发。调试半天,代码逻辑没问题,就是事件没响应。

原因: Vue 3 的组件事件名有明确规范:模板中用 @submit(kebab-case 也行 @submit),不是 @onSubmit。TinyRobot 的 Sender 组件事件名是 submitclearcancelfocusblurinput不带 on 前缀

修复:

vue 复制代码
<!-- ❌ 错误:加了 on 前缀 -->
<tr-sender @onSubmit="handleSend" @onClear="handleClear" />

<!-- ✅ 正确:直接用事件名 -->
<tr-sender @submit="handleSend" @clear="handleClear" />

<!-- ✅ 也可以用 kebab-case(不过 submit 本身没有大小写变化) -->
<tr-sender @submit="handleSend" />

其他常见易混淆事件:

你可能写的 正确事件名 说明
@onSubmit @submit Sender 提交事件
@onCancel @cancel Sender 取消事件(v0.4 新增)
@onFilesSelected @select(UploadButton) v0.4 改了,不在 Sender 上了
@onSpeechEnd @speech-end(VoiceButton) v0.4 移到 VoiceButton 组件
@onChange @blur@input v0.4 移除了 change 事件

v0.4 的最大变化是语音、文件上传相关事件从 Sender 移到了独立组件(VoiceButton、UploadButton),记得对应调整。


总结速查表

一句话记忆
1 样式必引@opentiny/tiny-robot/dist/style.css 不能忘
2 Tr 前缀 :组件名是 TrBubble,标签是 <tr-bubble>
3 别混用:全局引入和按需引入选一个
4 Node >= 20.13.0:低版本构建失败,报错还不好看
5 ThemeProvider 包裹:主题切换的前提条件
6 setup 中调用:useMessage 别跑到异步回调里
7 SenderCompat 过渡:v0.3.x 升级 v0.4 的快速通道
8 sseStreamToGenerator:SSE 流必须转 AsyncGenerator
9 按需引入优先:Tree Shaking 是你的好朋友
10 不带 on 前缀 :事件名是 submit 不是 onSubmit

踩坑是学习的必经之路,但重复踩同一个坑就没必要了。希望这篇能帮你绕过这些常见陷阱,把精力放在真正有价值的地方------构建出色的 AI 对话体验。

如果遇到文档没覆盖的问题,直接去 GitHub Issues 提问,社区响应很快的。


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 ⭐)

相关推荐
持敬chijing1 小时前
Web渗透之前后端漏洞-文件上传漏洞-过滤绕过与配置文件漏洞-条件竞争漏洞
前端·安全·web安全·网络安全·网络攻击模型·安全威胁分析
尼斯湖皮皮怪1 小时前
iceCoder:验收门控深度分析
前端·agent
周庆猛1 小时前
Babylon.js 多灯场景在 Windows 上报错:VERTEX shader uniform block count exceeds GL_MAX_VE
前端·数据可视化
胡志辉1 小时前
深入浅出理解浏览器事件循环:从一道输出题讲到 Chrome 源码
前端·javascript·面试
槑有老呆1 小时前
用 Bun 写一个 RESTful TodoList,顺便把面向接口编程整明白
前端
英勇无比的消炎药1 小时前
别再盲目混用AI组件库和传统组件库差距原来这么大
前端·vue.js
ViavaCos1 小时前
AI 帮我写代码,我帮 AI 踩坑:Vue 大数据表格优化全记录
前端·性能优化
lichenyang4532 小时前
聊天消息的「状态」该怎么存?从一堆 boolean 到一个状态机
前端
gz-郭小敏2 小时前
优化横向滚动展示大量数据的时候数据晃动问题
前端·javascript·html·css3