TinyRobot Container:构建优雅的 AI 对话容器
在构建 AI 对话应用时,一个合适的容器组件是至关重要的。它不仅仅是一个包裹内容的壳子------它需要处理布局定位、全屏切换、响应式适配,还要为对话区域、输入区域和操作栏提供合理的空间分配。如果你曾手动实现过这些功能,一定体会过定位错乱、全屏适配困难、输入框遮挡消息等令人头疼的问题。
TinyRobot 的 TrContainer 组件正是为解决这些痛点而生的。它开箱即用地提供了 AI 对话容器所需的一切能力:显示/隐藏控制、全屏模式、标题栏定制、底部输入区固定,以及通过 CSS 变量实现的灵活样式定制。
基本用法
TrContainer 最核心的功能是通过 v-model:show 控制容器的显示与隐藏。这是一个必填属性,让你可以在任何页面中轻松切换 AI 对话面板的可见性。
vue
<template>
<tr-container v-model:show="show">
<div class="content">
<p>欢迎使用 TinyRobot AI 助手</p>
</div>
</tr-container>
<button @click="show = !show">切换容器</button>
</template>
<script setup lang="ts">
import { TrContainer } from '@opentiny/tiny-robot'
import { ref } from 'vue'
const show = ref(false)
</script>
通过 v-model:show 双向绑定,容器的显示状态完全由你的数据驱动。当用户关闭容器时,你可以监听 close 事件来执行额外逻辑:
vue
<template>
<tr-container v-model:show="show" @close="handleClose">
<div class="content">对话内容</div>
</tr-container>
</template>
<script setup lang="ts">
import { TrContainer } from '@opentiny/tiny-robot'
import { ref } from 'vue'
const show = ref(true)
const handleClose = () => {
console.log('容器已关闭')
// Can perform cleanup logic here, e.g. clear conversation
}
</script>
全屏模式
AI 对话场景经常需要在侧边栏和全屏之间切换------简单问答用侧边栏即可,深度对话则希望有更大的阅读空间。TrContainer 通过 v-model:fullscreen 提供了优雅的全屏切换能力。
vue
<template>
<tr-container v-model:show="show" v-model:fullscreen="fullscreen">
<div class="content">
<p v-for="i in 20" :key="i">这是一段对话内容</p>
</div>
<template #footer>
<div class="footer">输入区域</div>
</template>
</tr-container>
<div style="display: flex; flex-direction: column; gap: 8px">
<div>
<label>show:</label>
<input type="checkbox" v-model="show" />
</div>
<div>
<label>fullscreen:</label>
<input type="checkbox" v-model="fullscreen" />
</div>
</div>
</template>
<script setup lang="ts">
import { TrContainer } from '@opentiny/tiny-robot'
import { ref } from 'vue'
const show = ref(false)
const fullscreen = ref(false)
</script>
<style scoped>
.content {
padding: 0 24px;
}
.footer {
padding: 16px 24px;
}
/* In fullscreen mode, limit content width on large screens */
.fullscreen {
@media (min-width: 1280px) {
.content,
.footer {
width: 1280px;
margin: 0 auto;
}
}
}
</style>
全屏模式下,Container 组件会自动添加 fullscreen 类名。你可以利用这个选择器来定制全屏时的内容布局,例如在大屏幕上限制内容宽度、居中显示,避免文本行过长影响阅读体验。
自定义标题与操作区
默认情况下,容器标题栏显示 "OpenTiny NEXT"。你可以通过 title 属性自定义标题文字,也可以通过 title 插槽完全定制标题区域的渲染内容。operations 插槽则让你在标题栏右侧添加操作按钮,如新建会话、查看历史等。
vue
<template>
<tr-container v-model:show="show" title="我的 AI 助手">
<!-- Custom title slot -->
<template #title>
<div style="display: flex; align-items: center; gap: 8px">
<span style="font-size: 20px">🤖</span>
<span>智能助手 Pro</span>
</div>
</template>
<!-- Operations slot: buttons on the right side of title bar -->
<template #operations>
<tr-icon-button size="28" svg-size="20" :icon="IconNewSession" @click="newSession" />
<tr-icon-button size="28" svg-size="20" :icon="IconHistory" @click="showHistory" />
</template>
<div class="content">
<p>对话内容区域</p>
</div>
</tr-container>
</template>
<script setup lang="ts">
import { TrContainer, TrIconButton } from '@opentiny/tiny-robot'
import { IconNewSession, IconHistory } from '@opentiny/tiny-robot-svgs'
import { ref } from 'vue'
const show = ref(true)
const newSession = () => {
console.log('创建新会话')
}
const showHistory = () => {
console.log('打开历史记录')
}
</script>
Footer 插槽:搭配 Sender 组件
footer 插槽是构建完整对话 UI 的关键。它固定在容器底部,非常适合放置 TrSender 输入组件,确保无论对话内容有多长,输入框始终可见可操作。
vue
<template>
<tr-container v-model:show="show" v-model:fullscreen="fullscreen">
<!-- Chat content area -->
<div class="messages">
<div v-for="msg in messages" :key="msg.id" :class="msg.role">
{{ msg.content }}
</div>
</div>
<!-- Footer slot: fixed at the bottom for input -->
<template #footer>
<div class="input-area" :class="{ 'max-container': fullscreen }">
<tr-sender
v-model="inputText"
mode="single"
:loading="isLoading"
placeholder="请输入您的问题..."
@submit="handleSubmit"
@cancel="handleCancel"
/>
</div>
</template>
</tr-container>
</template>
<script setup lang="ts">
import { TrContainer, TrSender } from '@opentiny/tiny-robot'
import { ref } from 'vue'
const show = ref(true)
const fullscreen = ref(false)
const inputText = ref('')
const isLoading = ref(false)
const messages = ref([
{ id: 1, role: 'assistant', content: '你好!有什么可以帮助你的吗?' },
])
const handleSubmit = () => {
if (!inputText.value.trim()) return
messages.value.push({
id: Date.now(),
role: 'user',
content: inputText.value,
})
isLoading.value = true
// Simulate AI response
setTimeout(() => {
messages.value.push({
id: Date.now() + 1,
role: 'assistant',
content: '收到,正在为你处理...',
})
isLoading.value = false
}, 1000)
inputText.value = ''
}
const handleCancel = () => {
isLoading.value = false
}
</script>
<style scoped>
.messages {
padding: 0 24px;
display: flex;
flex-direction: column;
gap: 12px;
}
.input-area {
padding: 8px 12px;
}
/* Fullscreen mode responsive layout */
.max-container {
@media (min-width: 1280px) {
width: 1280px;
margin: 0 auto;
}
}
</style>
CSS 变量定制
TrContainer 提供了丰富的 CSS 变量,让你无需修改组件源码即可深度定制容器外观。
全局变量
css
:root {
/* Container dimensions and borders */
--tr-container-width: 600px;
--tr-container-bg-color: #ffffff;
--tr-container-border-color: #e5e7eb;
--tr-container-border-width: 1px;
/* Header area */
--tr-container-header-padding: 16px 24px;
--tr-container-header-operations-gap: 4px;
/* Title styles */
--tr-container-title-color: #1f2937;
--tr-container-title-font-size: 16px;
--tr-container-title-font-weight: 600;
--tr-container-title-line-height: 24px;
}
全屏模式变量
全屏模式有独立的 CSS 变量,可以单独配置全屏时的标题大小、头部内边距等:
css
:root {
--tr-container-title-font-size-fullscreen: 20px;
--tr-container-title-line-height-fullscreen: 28px;
--tr-container-header-padding-fullscreen: 0 200px 24px;
}
实战:暗色主题定制
css
:root {
--tr-container-bg-color: #1a1a2e;
--tr-container-border-color: #2d2d44;
--tr-container-title-color: #e0e0ff;
--tr-container-title-font-size: 18px;
--tr-container-title-font-weight: 700;
--tr-container-width: 480px;
}
API 参考
Props
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
model:show |
boolean |
是 | - | 是否显示容器 |
model:fullscreen |
boolean |
否 | false |
是否全屏模式 |
title |
string |
否 | 'OpenTiny NEXT' |
容器标题 |
Slots
| 插槽名 | 说明 |
|---|---|
default |
容器主体内容 |
title |
自定义标题区域内容 |
operations |
标题栏右侧操作区 |
footer |
底部操作栏内容 |
Events
| 事件名 | 参数 | 说明 |
|---|---|---|
close |
- | 容器关闭时触发 |
CSS 变量
全局变量(:root)
| 变量名 | 说明 |
|---|---|
--tr-container-bg-color |
容器背景色 |
--tr-container-border-color |
容器边框色 |
--tr-container-border-width |
容器边框宽度 |
--tr-container-header-operations-gap |
操作按钮间距 |
--tr-container-header-padding |
头部内边距 |
--tr-container-title-color |
标题文字颜色 |
--tr-container-title-font-size |
标题字体大小 |
--tr-container-title-font-weight |
标题字体粗细 |
--tr-container-title-line-height |
标题行高 |
--tr-container-width |
容器宽度 |
全屏模式变量
| 变量名 | 说明 |
|---|---|
--tr-container-header-padding-fullscreen |
全屏模式头部内边距 |
--tr-container-title-font-size-fullscreen |
全屏模式标题字体大小 |
--tr-container-title-line-height-fullscreen |
全屏模式标题行高 |
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 ⭐)