MessageListState 概述
MessageListState 是一个与消息列表构建相关的状态管理中心,专为 Vue3 应用设计,用于管理消息列表的状态和操作。它利用 Vue3 的响应式系统,提供了消息列表的数据管理、分页加载、阅读回执设置、滚动控制等核心功能,是构建高性能、可定制聊天界面的重要工具。
MessageListState 采用了 Vue3 的 Composition API 和响应式设计,能够自动监听底层数据变化并更新组件状态,同时提供了丰富的业务操作方法来满足不同的使用场景。
什么时候需要 MessageListState?
当目前的
MessageList
组件能力无法满足您的特定需求,或者您希望基于底层数据重新开发一个自定义的消息列表时,可以使用 useMessageListState()
组合式函数来获取原始的数据源和相关的操作方法,进而进行灵活的定制和开发。属性列表
字段 | 类型 | 描述 |
Ref<readonly MessageModel[] | undefined> | 消息列表数据 | |
Ref<boolean | undefined> | 是否还有更多历史消息可加载 | |
Ref<boolean | undefined> | 是否启用阅读回执功能 | |
Ref<boolean | undefined> | 是否禁用滚动 | |
() => Promise<void> | 加载更多历史消息的方法 自动更新 messageList 和 hasMoreOlderMessage 状态 | |
(isDisableScroll: boolean) => void | 设置滚动状态的方法 | |
(enableReadReceipt: boolean | undefined) => void | 设置阅读回执状态的方法 |
属性详细说明
messageList
类型:Ref<readonly MessageModel[] | undefined>
详细说明:当前会话的消息列表数据。这是一个只读的响应式数组,包含了所有已加载的消息对象。每个消息对象包含消息内容、发送者信息、时间戳、状态等完整信息。没有激活会话时,该值为
undefined
。hasMoreOlderMessage
类型:Ref<boolean | undefined>
详细说明:标识是否还有更多的历史消息可以加载。当值为
true
时,表示还有更早的消息可以通过 loadMoreOlderMessage
方法获取;当值为 false
时,表示已经加载了所有历史消息;当值为 undefined
时,表示加载状态未确定。enableReadReceipt
类型:Ref<boolean | undefined>
详细说明:控制是否启用已读回执功能。这是一个响应式引用,当设置为
true
时,发送的消息会要求对方回执已读;当设置为 false
时,不要求对方发送已读回执;默认值为 false。注:该字段仅为一个布尔值,代表需要已读回执,要实现已读回执,发送消息时需要消费该字段。isDisableScroll
类型:Ref<boolean | undefined>
详细说明:控制消息列表的滚动行为。这是一个响应式引用,当设置为
true
时,禁用自动滚动功能;当设置为 false
时,允许正常滚动。通常在用户手动滚动查看历史消息时设置为 true
,避免新消息到达时自动滚动影响用户体验。该字段的设置不会禁用页面的滚动,请在 dom 侧使用该字段控制。loadMoreOlderMessage
类型:() => Promise<void>
详细说明:异步加载更多历史消息的方法。调用该方法会向服务器请求更早的消息数据,并自动更新
messageList
和 hasMoreOlderMessage
状态。setEnableReadReceipt
类型:(enableReadReceipt: boolean | undefined) => void
详细说明:用于设置阅读回执功能开关的方法。接收一个布尔值或
undefined
参数来控制是否启用阅读回执。setIsDisableScroll
类型:
(isDisableScroll: boolean) => void
详细说明:用于设置滚动状态的方法。接收一个布尔值参数来控制是否禁用滚动功能。
使用示例
以下是一个完整的
MessageList
组件示例,展示了如何使用 messageList
、hasMoreOlderMessage
和 loadMoreOlderMessage
来构建一个具有分页加载功能的消息列表:<template><div :class="['im-message-list-container']"><!-- 消息列表 --><div ref="messageListRef" class="message-list" @scroll="handleScroll"><div v-for="message in messageList" :key="message.ID" class="message-item"><div class="message-sender">{{ message.nick || message.from }}</div><div class="message-content"><span v-if="message.type === MessageType.TEXT" class="text-message">{{ message.payload.text }}</span><span v-else-if="message.type === MessageType.IMAGE" class="image-message">This is an image message</span><span v-else-if="message.type === MessageType.CUSTOM" class="custom-message">This is a custom message</span><span v-else>other message</span></div><div class="message-time">{{ new Date(message.time * 1000).toLocaleTimeString() }}</div></div></div><!-- 空状态 --><div v-if="!messageList || messageList?.length === 0" class="empty-state">暂无消息</div></div></template><script lang="ts" setup>import { ref, watch, onMounted, nextTick } from 'vue';import { useMessageListState, MessageType } from '@tencentcloud/chat-uikit-vue3';const {messageList,hasMoreOlderMessage,loadMoreOlderMessage,isDisableScroll,setIsDisableScroll,} = useMessageListState();const isLoading = ref(false);const messageListRef = ref<HTMLDivElement | null>(null);const prevScrollHeight = ref(0);// 加载更多消息const handleLoadMore = async () => {if (isLoading.value || !hasMoreOlderMessage.value) {return;}isLoading.value = true;try {// 记录当前滚动高度if (messageListRef.value) {prevScrollHeight.value = messageListRef.value.scrollHeight;}await loadMoreOlderMessage();} catch (error) {console.error('加载更多消息失败:', error);} finally {isLoading.value = false;}};// 处理滚动事件const handleScroll = (e: Event) => {const target = e.target as HTMLDivElement;const { scrollTop, scrollHeight, clientHeight } = target;// 检测是否滚动到顶部,触发加载更多if (scrollTop === 0 && hasMoreOlderMessage.value && !isLoading.value) {handleLoadMore();}// 检测用户是否在查看历史消息const isAtBottom = scrollTop + clientHeight >= scrollHeight - 10;setIsDisableScroll(!isAtBottom);};// 保持滚动位置(加载更多消息后)watch(messageList, () => {nextTick(() => {if (messageListRef.value && prevScrollHeight.value > 0) {const newScrollHeight = messageListRef.value.scrollHeight;const scrollDiff = newScrollHeight - prevScrollHeight.value;messageListRef.value.scrollTop = scrollDiff;prevScrollHeight.value = 0;}});});// 自动滚动到底部(新消息到达时)watch([messageList, isDisableScroll], () => {nextTick(() => {if (messageListRef.value && !isDisableScroll.value) {messageListRef.value.scrollTop = messageListRef.value.scrollHeight;}});});onMounted(() => {// 初始加载完成后滚动到底部nextTick(() => {if (messageListRef.value) {messageListRef.value.scrollTop = messageListRef.value.scrollHeight;}});});</script><style scoped lang="scss">.im-message-list-container {display: flex;flex-direction: column;flex: 1 1 auto;overflow: auto hidden;height: 100%; // Ensure container has a height.message-list {flex: 1;overflow-y: auto;min-height: 0; // Important for flex container with overflowpadding: 10px;.message-item {margin-bottom: 15px;padding: 10px;background: #f5f5f5;border-radius: 8px;.message-sender {font-weight: bold;color: #333;margin-bottom: 5px;}.message-content {color: #666;line-height: 1.5;margin-bottom: 5px;}.message-time {font-size: 12px;color: #999;text-align: right;}}}.empty-state {flex: 1;display: flex;align-items: center;justify-content: center;color: #999;font-size: 14px;}}</style>
示例效果图:

这个示例展示了如何:
使用
messageList
渲染消息列表。调用
loadMoreOlderMessage
实现滚动到顶部自动加载历史消息。结合
isDisableScroll
和 setIsDisableScroll
优化滚动体验。处理加载状态和空状态的显示。
扩展资料
MessageModel
类型常用字段:// MessageModel 接口定义,详细内容请参考 @tencentcloud/chat-uikit-engine 文档// 这是一个复杂的消息模型,包含消息ID、类型、发送者、内容、时间、状态等属性。// 示例结构 (非完整定义):interface MessageModel {ID: string;conversationID: string;type: MessageType;payload: any;flow: 'in' | 'out';from: string;to: string;time: number; // Unix 时间戳 (秒)status: 'unSend' | 'success' | 'fail';isDeleted: boolean;isRevoked: boolean;hasRiskContent: boolean; // 是否包含风险内容// ... 其他属性}
相关文档
交流与反馈