ConversationList 对话列表
对话历史列表容器,支持自动滚动到底部和加载更多历史消息。
基础用法
<script setup>
import ConversationList from '@/vue/components/ConversationList.vue'
import ChatMessage from '@/vue/components/ChatMessage.vue'
</script>
<template>
<div style="border: 1px solid var(--vk-border-color); border-radius: 4px;">
<ConversationList height="300px">
<ChatMessage role="user" :timestamp="new Date(Date.now() - 120000)">
你好,我想学习 Vue 3
</ChatMessage>
<ChatMessage role="assistant" :timestamp="new Date(Date.now() - 60000)">
你好!很高兴你想学习 Vue 3。Vue 3 是一个渐进式 JavaScript 框架,它的核心特性包括组合式 API、更好的 TypeScript 支持和性能优化。
</ChatMessage>
<ChatMessage role="user" :timestamp="new Date()">
能给我一个简单的例子吗?
</ChatMessage>
<ChatMessage role="assistant" :timestamp="new Date()">
当然可以!下面是一个最简单的 Vue 3 组件示例。
</ChatMessage>
</ConversationList>
</div>
</template>加载更多
滚动到顶部时触发 load-more 事件。
<script setup>
import { ref } from 'vue'
import ConversationList from '@/vue/components/ConversationList.vue'
import ChatMessage from '@/vue/components/ChatMessage.vue'
let nextId = 1
const loading = ref(false)
const messages = ref([
{ id: nextId++, role: 'assistant', content: '历史消息 1:这是较早的一轮回复。', timestamp: new Date(Date.now() - 360000) },
{ id: nextId++, role: 'user', content: '历史消息 2:继续追问一个细节。', timestamp: new Date(Date.now() - 300000) },
{ id: nextId++, role: 'assistant', content: '历史消息 3:补充上下文和说明。', timestamp: new Date(Date.now() - 240000) },
{ id: nextId++, role: 'user', content: '当前问题:滚动到顶部加载更多历史消息。', timestamp: new Date(Date.now() - 180000) },
{ id: nextId++, role: 'assistant', content: '向上滚动到顶部会触发 load-more。', timestamp: new Date(Date.now() - 120000) },
{ id: nextId++, role: 'assistant', content: '加载中状态会阻止重复触发。', timestamp: new Date(Date.now() - 60000) }
])
function handleLoadMore() {
if (loading.value) return
loading.value = true
setTimeout(() => {
const older = [
{ id: nextId++, role: 'assistant', content: '更早的历史消息:组件会把它插入到顶部。', timestamp: new Date(Date.now() - 480000) },
{ id: nextId++, role: 'user', content: '更早的用户提问。', timestamp: new Date(Date.now() - 420000) }
]
messages.value = [...older, ...messages.value]
loading.value = false
}, 900)
}
</script>
<template>
<ConversationList height="200px" :loading-more="loading" @load-more="handleLoadMore">
<ChatMessage
v-for="message in messages"
:key="message.id"
:role="message.role"
:timestamp="message.timestamp"
>
{{ message.content }}
</ChatMessage>
</ConversationList>
</template>React 用法
tsx
import { ConversationList, ChatMessage } from '@bobocn/element/react'
import '@bobocn/element/style.css'
function App() {
return (
<ConversationList height="400px" onLoadMore={() => console.log('load more')}>
<ChatMessage role="user" timestamp={new Date()}>Hello</ChatMessage>
<ChatMessage role="assistant" timestamp={new Date()}>Hi!</ChatMessage>
</ConversationList>
)
}API
属性 (Attributes)
| 属性名 | 说明 | 类型 | 默认值 |
|---|---|---|---|
| autoScroll | 新消息自动滚到底部 | boolean | true |
| loadingMore | 正在加载历史消息 | boolean | false |
| height | 容器高度 | string | — |
| maxHeight | 容器最大高度 | string | '100%' |
| preserveScrollOnPrepend | 加载历史消息时保持当前滚动位置 | boolean | true |
| emptyText | 空状态文案 | string | '暂无对话' |
事件 (Events)
| 事件名 | 说明 | 回调参数 |
|---|---|---|
| load-more / onLoadMore | 滚动到顶部时触发 | — |
| scroll / onScroll | 滚动时触发 | (scrollTop: number) |
方法 (Exposes / Ref)
| 方法名 | 说明 | 类型 |
|---|---|---|
| scrollToBottom | 滚动到底部 | () => void |
| getElement | 获取滚动容器 DOM | () => HTMLElement | null |
插槽 (Slots)
| 插槽名 | 说明 |
|---|---|
| default | 对话消息列表 |
