Skip to content

ConversationList 对话列表

对话历史列表容器,支持自动滚动到底部和加载更多历史消息。

基础用法

你好,我想学习 Vue 3
03:27
你好!很高兴你想学习 Vue 3。Vue 3 是一个渐进式 JavaScript 框架,它的核心特性包括组合式 API、更好的 TypeScript 支持和性能优化。
03:28
能给我一个简单的例子吗?
03:29
当然可以!下面是一个最简单的 Vue 3 组件示例。
03:29
<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 事件。

历史消息 1:这是较早的一轮回复。
03:23
历史消息 2:继续追问一个细节。
03:24
历史消息 3:补充上下文和说明。
03:25
当前问题:滚动到顶部加载更多历史消息。
03:26
向上滚动到顶部会触发 load-more。
03:27
加载中状态会阻止重复触发。
03:28
<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新消息自动滚到底部booleantrue
loadingMore正在加载历史消息booleanfalse
height容器高度string
maxHeight容器最大高度string'100%'
preserveScrollOnPrepend加载历史消息时保持当前滚动位置booleantrue
emptyText空状态文案string'暂无对话'

事件 (Events)

事件名说明回调参数
load-more / onLoadMore滚动到顶部时触发
scroll / onScroll滚动时触发(scrollTop: number)

方法 (Exposes / Ref)

方法名说明类型
scrollToBottom滚动到底部() => void
getElement获取滚动容器 DOM() => HTMLElement | null

插槽 (Slots)

插槽名说明
default对话消息列表

基于 MIT 许可发布