用 TinyRobot Welcome 组件打造贴心的 AI 助手欢迎页
当用户第一次打开 AI 助手时,映入眼帘的往往是空荡荡的对话框------没有引导、没有提示,用户不知道该问什么、能问什么。这种"空白画布焦虑"会极大影响用户的第一印象和使用意愿。
一个精心设计的欢迎页,能够瞬间拉近用户与 AI 的距离:一句温暖的问候让用户感受到被关注,一段简洁的功能描述帮助用户了解能力边界,一组引导性提示词则让用户无需思考即可开始对话。TinyRobot 的 TrWelcome 组件正是为此而生,它提供了标题、描述、图标、对齐方式和底部扩展插槽,让你可以快速构建出专业且贴心的 AI 助手欢迎页。
基本用法
TrWelcome 的核心是 title 和 description 两个必填属性,分别用于设置欢迎标题和功能描述。
vue
<template>
<tr-welcome
title="TinyRobot"
description="您好,我是 TinyRobot,您专属的 AI 智能专家"
/>
</template>
<script setup lang="ts">
import { TrWelcome } from '@opentiny/tiny-robot'
</script>
仅用两行属性,你就得到了一个居中对齐、带有默认图标的欢迎页面。标题突出展示,描述文字清晰可读,用户一眼就能了解这个 AI 助手的定位。
对齐方向
不同的容器布局需要不同的对齐方式。侧边栏对话面板中,内容左对齐更自然;居中弹窗中,居中对齐更协调;TrWelcome 通过 align 属性支持三种对齐模式。
vue
<template>
<div style="display: flex; flex-direction: column; gap: 24px">
<!-- Left aligned: suitable for sidebar panels -->
<tr-welcome
title="AI 编程助手"
description="帮您编写代码、审查 PR、解答技术问题"
align="left"
/>
<!-- Center aligned (default): suitable for centered dialogs -->
<tr-welcome
title="AI 编程助手"
description="帮您编写代码、审查 PR、解答技术问题"
align="center"
/>
<!-- Right aligned: suitable for special layouts -->
<tr-welcome
title="AI 编程助手"
description="帮您编写代码、审查 PR、解答技术问题"
align="right"
/>
</div>
</template>
<script setup lang="ts">
import { TrWelcome } from '@opentiny/tiny-robot'
</script>
align 属性接受 'left'、'center'、'right' 三个值,默认为 'center'。在大多数 AI 对话场景中,居中对齐是最常见的选择,因为它与容器整体的对称布局最为协调。
自定义图标
默认图标虽然简洁,但往往无法体现产品的品牌特色。TrWelcome 的 icon 属性接受 VNode 类型,你可以传入任意 Vue 组件或 JSX 来定制欢迎图标。
vue
<template>
<tr-welcome
title="TinyRobot"
description="您好,我是 TinyRobot,您专属的 AI 智能专家"
:icon="customIcon"
/>
</template>
<script setup lang="ts">
import { TrWelcome } from '@opentiny/tiny-robot'
import { IconAi } from '@opentiny/tiny-robot-svgs'
import { h } from 'vue'
// Use SVG icon from tiny-robot-svgs
const customIcon = h(IconAi, { style: { fontSize: '48px' } })
</script>
你可以使用 @opentiny/tiny-robot-svgs 提供的图标,也可以传入任何自定义 SVG 组件,甚至通过 h() 函数创建带有样式的内联元素:
vue
<script setup lang="ts">
import { h } from 'vue'
// Emoji icon
const emojiIcon = h('span', { style: { fontSize: '48px' } }, '🤖')
// Custom styled element
const brandIcon = h('div', {
style: {
width: '48px',
height: '48px',
borderRadius: '50%',
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
color: '#fff',
fontSize: '24px',
},
}, 'AI')
</script>
Footer 插槽:搭配 Prompts 组件
这是 TrWelcome 最实用的特性------footer 插槽让你可以在欢迎信息下方添加引导性提示词。结合 TrPrompts 组件,你可以为用户提供一键式对话入口,消除"不知道该问什么"的困惑。
vue
<template>
<tr-welcome
title="AI 助手"
description="我可以帮你编写代码、分析数据、撰写文档,点击下方提示快速开始"
>
<template #footer>
<tr-prompts
:items="promptItems"
:wrap="true"
@item-click="handlePromptClick"
/>
</template>
</tr-welcome>
</template>
<script setup lang="ts">
import { TrWelcome, TrPrompts } from '@opentiny/tiny-robot'
import type { PromptProps } from '@opentiny/tiny-robot'
import { h } from 'vue'
const promptItems: PromptProps[] = [
{
label: '编写代码',
description: '根据需求生成高质量的代码实现',
icon: h('span', { style: { fontSize: '18px' } }, '💻'),
},
{
label: '分析数据',
description: '对数据进行智能分析和可视化建议',
icon: h('span', { style: { fontSize: '18px' } }, '📊'),
},
{
label: '撰写文档',
description: '快速生成技术文档和 API 说明',
icon: h('span', { style: { fontSize: '18px' } }, '📝'),
},
{
label: '代码审查',
description: '审查代码质量并提供优化建议',
icon: h('span', { style: { fontSize: '18px' } }, '🔍'),
},
]
const handlePromptClick = (ev: MouseEvent, item: PromptProps) => {
if (item.description) {
console.log('用户选择了:', item.description)
// Can directly send as the conversation message
}
}
</script>
通过这种方式,用户只需点击一个提示卡片即可开启对话,无需在空白的输入框前犹豫。TrPrompts 还支持 vertical(纵向排列)、wrap(自动换行)、size(尺寸调整)等属性,可以根据容器空间灵活适配。
综合实战:搭配 Container 构建完整对话布局
TrWelcome 最常见的使用场景是作为对话容器中的初始状态------当对话尚未开始时显示欢迎页,用户发送第一条消息后切换为对话列表。结合 TrContainer,可以快速构建出完整的 AI 对话界面。
vue
<template>
<tr-container v-model:show="show" v-model:fullscreen="fullscreen" title="AI 智能助手">
<template #operations>
<tr-icon-button size="28" svg-size="20" :icon="IconNewSession" @click="resetChat" />
</template>
<!-- Welcome page: shown when no messages -->
<div v-if="messages.length === 0" :class="{ 'max-container': fullscreen }">
<tr-welcome
title="TinyRobot"
description="您好,我是 TinyRobot,您专属的 AI 智能专家"
:icon="welcomeIcon"
>
<template #footer>
<tr-prompts
:items="promptItems"
:wrap="true"
item-class="prompt-item"
@item-click="handlePromptClick"
/>
</template>
</tr-welcome>
</div>
<!-- Chat messages: shown after conversation starts -->
<div v-else :class="{ 'max-container': fullscreen }" class="messages">
<div v-for="msg in messages" :key="msg.id" :class="['message', msg.role]">
{{ msg.content }}
</div>
</div>
<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>
<div style="display: flex; gap: 8px">
<label><input type="checkbox" v-model="show" /> 显示</label>
<label><input type="checkbox" v-model="fullscreen" /> 全屏</label>
</div>
</template>
<script setup lang="ts">
import { TrContainer, TrWelcome, TrPrompts, TrSender, TrIconButton } from '@opentiny/tiny-robot'
import type { PromptProps } from '@opentiny/tiny-robot'
import { IconAi, IconNewSession } from '@opentiny/tiny-robot-svgs'
import { h, ref } from 'vue'
const show = ref(true)
const fullscreen = ref(false)
const inputText = ref('')
const isLoading = ref(false)
const welcomeIcon = h(IconAi, { style: { fontSize: '48px' } })
const promptItems: PromptProps[] = [
{
label: '编写代码',
description: '请帮我编写一个 Vue3 组合式 API 的表单组件',
icon: h('span', { style: { fontSize: '18px' } }, '💻'),
},
{
label: '数据分析',
description: '帮我分析这份销售数据的关键趋势',
icon: h('span', { style: { fontSize: '18px' } }, '📊'),
},
{
label: '文档撰写',
description: '为我生成一份 RESTful API 设计文档',
icon: h('span', { style: { fontSize: '18px' } }, '📝'),
},
{
label: '代码审查',
description: '请审查我提交的 PR 并提供优化建议',
icon: h('span', { style: { fontSize: '18px' } }, '🔍'),
},
]
const messages = ref<{ id: number; role: string; content: string }[]>([])
const sendMessage = (content: string) => {
if (!content.trim()) return
messages.value.push({ id: Date.now(), role: 'user', content })
isLoading.value = true
setTimeout(() => {
messages.value.push({
id: Date.now() + 1,
role: 'assistant',
content: '收到您的问题,正在为您分析...',
})
isLoading.value = false
}, 1000)
}
const handleSubmit = () => {
sendMessage(inputText.value)
inputText.value = ''
}
const handleCancel = () => {
isLoading.value = false
}
const handlePromptClick = (_ev: MouseEvent, item: PromptProps) => {
if (item.description) {
sendMessage(item.description)
}
}
const resetChat = () => {
messages.value = []
}
</script>
<style scoped>
.max-container {
@media (min-width: 1280px) {
width: 1280px;
margin: 0 auto;
}
}
.messages {
padding: 0 24px;
display: flex;
flex-direction: column;
gap: 12px;
}
.message {
padding: 12px 16px;
border-radius: 12px;
max-width: 80%;
}
.message.user {
background: #1476ff;
color: #fff;
align-self: flex-end;
}
.message.assistant {
background: #f5f5f5;
align-self: flex-start;
}
.input-area {
padding: 8px 12px;
}
</style>
这个示例展示了一个完整的 AI 对话应用架构:
- 初始状态 :
TrWelcome+TrPrompts构建欢迎引导页,用户可以点击提示词快速开始 - 对话状态:切换为消息列表,展示用户和 AI 的对话内容
- 输入区域 :
TrSender固定在容器底部,始终保持可操作 - 全屏适配 :通过
fullscreen类名控制大屏下的内容宽度
API 参考
Props
| 属性 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
title |
string |
是 | - | 标题 |
description |
string |
是 | - | 标题描述 |
align |
`'left' | 'center' | 'right'` | 否 |
icon |
VNode |
否 | - | 自定义图标节点,支持 Vue 组件或 JSX |
Slots
| 插槽名 | 说明 |
|---|---|
footer |
组件底部内容插槽 |
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 ⭐)