ChatList 对话列表
对话容器,支持自动滚到底部、stickToBottom(用户手动滚开时停止自动滚)、按 role / date 分组、"回到最新" 浮动按钮。
基础用法
把 CfChatBubble(或任意子组件)放在默认 slot 里。新内容到来时,组件用 useResizeObserver 监听内层高度变化,自动滚到底部;若 stickToBottom=true 且用户向上滚开,会暂停自动滚直到用户回到底部。右下角的”回到最新”按钮在脱离底部时自动出现。
背景 视口
帮我列出 ChuFix UI 的所有图表组件。
当前共有 28 种图表,包含 LineChart / AreaChart / BarChart / DonutChart / Treemap / SankeyDiagram 等。
它们都支持鼠标事件吗?
是的,全部支持 item-enter / item-leave / click 等事件,部分支持 node / link / vertex 级别事件。
<script setup lang="ts">
import { ref } from 'vue';
import { CfChatList, CfChatBubble, CfButton } from '@chufix-design/vue';
interface Msg { id: number; role: 'user' | 'assistant'; content: string; }
const messages = ref<Msg[]>([
{ id: 1, role: 'user', content: '帮我列出 ChuFix UI 的所有图表组件。' },
{ id: 2, role: 'assistant', content: '当前共有 28 种图表,包含 LineChart / AreaChart / BarChart / DonutChart / Treemap / SankeyDiagram 等。' },
{ id: 3, role: 'user', content: '它们都支持鼠标事件吗?' },
{ id: 4, role: 'assistant', content: '是的,全部支持 item-enter / item-leave / click 等事件,部分支持 node / link / vertex 级别事件。' },
]);
function appendOne() {
messages.value.push({
id: Date.now(),
role: 'assistant',
content: '已新增一条消息 — 列表会自动滚到底部(如果你之前在底部)。',
});
}
</script>
<template>
<div class="demo-stack">
<CfChatList style="height: 320px; border: 1px solid var(--line-1); border-radius: var(--r-4);">
<CfChatBubble
v-for="m in messages"
:key="m.id"
:role="m.role"
:content="m.content"
:author="{ name: m.role === 'user' ? '我' : 'Claude' }"
/>
</CfChatList>
<CfButton size="sm" variant="tertiary" @click="appendOne">新增一条消息</CfButton>
</div>
</template> <script setup>
import { ref } from 'vue';
import { CfChatList, CfChatBubble, CfButton } from '@chufix-design/vue';
const messages = ref<Msg[]>([
{ id: 1, role: 'user', content: '帮我列出 ChuFix UI 的所有图表组件。' },
{ id: 2, role: 'assistant', content: '当前共有 28 种图表,包含 LineChart / AreaChart / BarChart / DonutChart / Treemap / SankeyDiagram 等。' },
{ id: 3, role: 'user', content: '它们都支持鼠标事件吗?' },
{ id: 4, role: 'assistant', content: '是的,全部支持 item-enter / item-leave / click 等事件,部分支持 node / link / vertex 级别事件。' },
]);
function appendOne() {
messages.value.push({
id: Date.now(),
role: 'assistant',
content: '已新增一条消息 — 列表会自动滚到底部(如果你之前在底部)。',
});
}
</script>
<template>
<div class="demo-stack">
<CfChatList style="height: 320px; border: 1px solid var(--line-1); border-radius: var(--r-4);">
<CfChatBubble
v-for="m in messages"
:key="m.id"
:role="m.role"
:content="m.content"
:author="{ name: m.role === 'user' ? '我' : 'Claude' }"
/>
</CfChatList>
<CfButton size="sm" variant="tertiary" @click="appendOne">新增一条消息</CfButton>
</div>
</template> import { useState } from 'react';
import { CfButton, CfChatBubble, CfChatList } from '@chufix-design/react';
export default function Demo() {
interface Msg { id: number; role: 'user' | 'assistant'; content: string; }
const [messages, setMessages] = useState<Msg[]>([
{ id: 1, role: 'user', content: '帮我列出 ChuFix UI 的所有图表组件。' },
{ id: 2, role: 'assistant', content: '当前共有 28 种图表,包含 LineChart / AreaChart / BarChart / DonutChart / Treemap / SankeyDiagram 等。' },
{ id: 3, role: 'user', content: '它们都支持鼠标事件吗?' },
{ id: 4, role: 'assistant', content: '是的,全部支持 item-enter / item-leave / click 等事件,部分支持 node / link / vertex 级别事件。' },
]);
function appendOne() {
messages.push({
id: Date.now(),
role: 'assistant',
content: '已新增一条消息 — 列表会自动滚到底部(如果你之前在底部)。',
});
}
return (
<>
<div className="demo-stack">
<CfChatList style={{ height: 320, border: "1px solid var(--line-1)", borderRadius: "var(--r-4)" }}>
<CfChatBubble v-for="m in messages" key={m.id} role={m.role} content={m.content} author={{ name: m.role === 'user' ? '我' : 'Claude' }} />
</CfChatList>
<CfButton size="sm" variant="tertiary" onClick={appendOne}>新增一条消息</CfButton>
</div>
</>
);
} import { useState } from 'react';
import { CfButton, CfChatBubble, CfChatList } from '@chufix-design/react';
export default function Demo() {
const [messages, setMessages] = useState<Msg[]>([
{ id: 1, role: 'user', content: '帮我列出 ChuFix UI 的所有图表组件。' },
{ id: 2, role: 'assistant', content: '当前共有 28 种图表,包含 LineChart / AreaChart / BarChart / DonutChart / Treemap / SankeyDiagram 等。' },
{ id: 3, role: 'user', content: '它们都支持鼠标事件吗?' },
{ id: 4, role: 'assistant', content: '是的,全部支持 item-enter / item-leave / click 等事件,部分支持 node / link / vertex 级别事件。' },
]);
function appendOne() {
messages.push({
id: Date.now(),
role: 'assistant',
content: '已新增一条消息 — 列表会自动滚到底部(如果你之前在底部)。',
});
}
return (
<>
<div className="demo-stack">
<CfChatList style={{ height: 320, border: "1px solid var(--line-1)", borderRadius: "var(--r-4)" }}>
<CfChatBubble v-for="m in messages" key={m.id} role={m.role} content={m.content} author={{ name: m.role === 'user' ? '我' : 'Claude' }} />
</CfChatList>
<CfButton size="sm" variant="tertiary" onClick={appendOne}>新增一条消息</CfButton>
</div>
</>
);
} API
| 属性 | 类型 | 默认 | 说明 |
|---|---|---|---|
autoScroll | boolean | true | 内容增长时自动滚到底部 |
stickToBottom | boolean | true | 仅在用户已在底部时自动滚 |
stickThreshold | number | 64 | ”已在底部” 的距离阈值(px) |
groupBy | 'role' | 'date' | 'none' | 'role' | 视觉分组(目前主要用于间距) |
Imperative API
| 方法 | 说明 |
|---|---|
scrollToBottom(behavior?) | 手动滚到底部 — Vue 通过模板 ref,React 通过 forwardRef 暴露 |
反馈与讨论
ChatList 对话列表 的讨论