概述
ConversationListState 是基于 Vue 3 Composition API 的会话列表状态管理钩子,为 ConversationList 组件提供完整的状态管理能力。它管理会话列表数据、当前活跃会话、未读消息数量、网络状态等,并提供会话操作的相关方法。
数据
属性名 | 类型 | 说明 |
conversationList | Ref<ConversationModel[] | undefined> | 会话列表数据 |
activeConversation | Ref<ConversationModel | undefined> | 当前活跃的会话 |
totalUnRead | Ref<number> | 未读消息总数 |
netStatus | Ref<NET_STATE_CONNECTED | NET_STATE_CONNECTING | NET_STATE_DISCONNECTED> | 网络连接状态 |
方法
方法名 | 类型 | 说明 |
setActiveConversation | (conversationID: string) => void | 设置当前活跃会话 |
createC2CConversation | (userID: string) => Promise<ConversationModel> | 创建私聊会话 |
createGroupConversation | (options: CreateGroupParams) => Promise<ConversationModel> | 创建群聊会话 |
pinConversation | (conversationID: string, isPin: boolean) => Promise<unknown> | 置顶/取消置顶会话 |
deleteConversation | (conversationID: string) => Promise<unknown> | 删除会话 |
muteConversation | (conversationID: string, isMute: boolean) => Promise<unknown> | 免打扰/取消免打扰 |
setConversationDraft | (options: SetConversationDraftParams) => Promise<unknown> | 设置会话草稿 |
markConversationUnread | (conversationID: string, isUnread: boolean) => void | 标记会话已读/未读 |
网络状态
支持以下网络状态类型:
NET_STATE_CONNECTED:已连接
NET_STATE_CONNECTING:连接中
NET_STATE_DISCONNECTED:已断开
使用示例
基础会话列表
<template><div class="conversation-list"><div class="header"><h3>会话列表</h3><div v-if="totalUnRead > 0" class="unread-badge">{{ totalUnRead }}</div></div><div class="list"><divv-for="conversation in conversationList":key="conversation.conversationID":class="['conversation-item',{ active: activeConversation?.conversationID === conversation.conversationID }]"@click="setActiveConversation(conversation.conversationID)"><div class="avatar"><img :src="conversation.getAvatar()" alt="头像" /></div><div class="content"><div class="name">{{ conversation.getShowName() }}</div><div class="last-message">{{ conversation.lastMessage?.messageForShow }}</div></div><div v-if="conversation.unreadCount > 0" class="unread-count">{{ conversation.unreadCount }}</div></div></div></div></template><script setup lang="ts">import { useConversationListState } from '@tencentcloud/chat-uikit-vue3';const {conversationList,activeConversation,totalUnRead,setActiveConversation} = useConversationListState();</script><style scoped>.conversation-list {width: 300px;height: 100%;border-right: 1px solid #e0e0e0;}.header {display: flex;justify-content: space-between;align-items: center;padding: 16px;border-bottom: 1px solid #f0f0f0;}.unread-badge {background: #ff4d4f;color: white;border-radius: 50%;width: 20px;height: 20px;display: flex;align-items: center;justify-content: center;font-size: 12px;font-weight: 600;}.conversation-item {display: flex;align-items: center;padding: 12px 16px;cursor: pointer;border-bottom: 1px solid #f5f5f5;transition: background-color 0.2s;}.conversation-item:hover {background-color: #f5f5f5;}.conversation-item.active {background-color: #e6f7ff;border-left: 3px solid #1890ff;}.avatar {width: 40px;height: 40px;margin-right: 12px;}.avatar img {width: 100%;height: 100%;border-radius: 50%;object-fit: cover;}.content {flex: 1;min-width: 0;}.name {font-weight: 500;margin-bottom: 4px;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;}.last-message {font-size: 13px;color: #999;white-space: nowrap;overflow: hidden;text-overflow: ellipsis;}.unread-count {background: #52c41a;color: white;border-radius: 10px;padding: 2px 6px;font-size: 12px;font-weight: 600;min-width: 18px;text-align: center;}</style>
效果如图:

会话操作功能
<template><div class="conversation-with-actions"><divv-for="conversation in conversationList":key="conversation.conversationID"class="conversation-item"><div class="conversation-info"><div class="name">{{ conversation.getShowName() }}</div><div class="status"><span v-if="conversation.isPinned" class="pin-badge">📌 置顶</span><span v-if="conversation.isMuted" class="mute-badge">🔕 免打扰</span><span v-if="conversation.unreadCount > 0" class="unread-badge">{{ conversation.unreadCount }}</span></div></div><div class="conversation-actions"><button@click="handlePin(conversation.conversationID, !conversation.isPinned)":class="{ active: conversation.isPinned }">{{ conversation.isPinned ? '取消置顶' : '置顶' }}</button><button@click="handleMute(conversation.conversationID, !conversation.isMuted)":class="{ active: conversation.isMuted }">{{ conversation.isMuted ? '取消免打扰' : '免打扰' }}</button><button@click="handleMarkUnread(conversation.conversationID, conversation.unreadCount === 0)">{{ conversation.unreadCount > 0 ? '标记已读' : '标记未读' }}</button><button@click="handleDelete(conversation.conversationID)"class="danger">删除</button></div></div></div></template><script setup lang="ts">import { useConversationListState } from '@tencentcloud/chat-uikit-vue3';const {conversationList,pinConversation,deleteConversation,muteConversation,markConversationUnread} = useConversationListState();const handlePin = async (conversationID: string, isPin: boolean) => {try {await pinConversation(conversationID, isPin);console.log(`会话${isPin ? '置顶' : '取消置顶'}成功`);} catch (error) {console.error('置顶操作失败:', error);}};const handleDelete = async (conversationID: string) => {if (confirm('确定要删除这个会话吗?')) {try {await deleteConversation(conversationID);console.log('会话删除成功');} catch (error) {console.error('删除会话失败:', error);}}};const handleMute = async (conversationID: string, isMute: boolean) => {try {await muteConversation(conversationID, isMute);console.log(`会话${isMute ? '设置' : '取消'}免打扰成功`);} catch (error) {console.error('免打扰设置失败:', error);}};const handleMarkUnread = (conversationID: string, isUnread: boolean) => {markConversationUnread(conversationID, isUnread);console.log(`会话标记为${isUnread ? '未读' : '已读'}`);};</script><style scoped>.conversation-item {display: flex;justify-content: space-between;align-items: center;padding: 16px;border-bottom: 1px solid #f0f0f0;}.conversation-info {flex: 1;}.name {font-weight: 500;margin-bottom: 8px;}.status {display: flex;gap: 8px;align-items: center;}.pin-badge, .mute-badge {font-size: 12px;color: #666;}.unread-badge {background: #52c41a;color: white;border-radius: 10px;padding: 2px 6px;font-size: 12px;font-weight: 600;}.conversation-actions {display: flex;gap: 8px;}.conversation-actions button {padding: 6px 12px;border: 1px solid #d9d9d9;border-radius: 4px;background: white;cursor: pointer;font-size: 12px;transition: all 0.2s;}.conversation-actions button:hover {border-color: #1890ff;color: #1890ff;}.conversation-actions button.active {background: #1890ff;border-color: #1890ff;color: white;}.conversation-actions button.danger {border-color: #ff4d4f;color: #ff4d4f;}.conversation-actions button.danger:hover {background: #ff4d4f;color: white;}</style>
效果如图:

创建会话功能
<template><div class="conversation-creator"><div class="create-c2c"><h4>创建私聊</h4><div class="form-group"><inputv-model="userID"type="text"placeholder="输入用户ID"@keyup.enter="handleCreateC2C"/><button @click="handleCreateC2C" :disabled="!userID.trim()">创建私聊</button></div></div><div class="create-group"><h4>创建群聊</h4><div class="form-group"><inputv-model="groupName"type="text"placeholder="输入群组名称"/></div><div class="form-group"><label>群组类型:</label><select v-model="groupType"><option value="Work">工作群</option><option value="Public">公开群</option><option value="Meeting">会议群</option></select></div><div class="member-selector"><label>群成员 (用户ID,逗号分隔):</label><textareav-model="memberList"placeholder="user1,user2,user3"rows="3"></textarea></div><button@click="handleCreateGroup":disabled="!groupName.trim() || !memberList.trim()">创建群聊</button></div></div></template><script setup lang="ts">import { ref } from 'vue';import { useConversationListState } from '@tencentcloud/chat-uikit-vue3';import type { CreateGroupParams } from '@tencentcloud/chat-uikit-engine';const {createC2CConversation,createGroupConversation,setActiveConversation} = useConversationListState();const userID = ref('');const groupName = ref('');const groupType = ref<'Work' | 'Public' | 'Meeting'>('Work');const memberList = ref('');const handleCreateC2C = async () => {if (!userID.value.trim()) {alert('请输入用户ID');return;}try {const conversation = await createC2CConversation(userID.value);setActiveConversation(conversation.conversationID);console.log('私聊创建成功:', conversation.conversationID);userID.value = '';} catch (error) {console.error('创建私聊失败:', error);alert('创建私聊失败,请检查用户ID是否正确');}};const handleCreateGroup = async () => {if (!groupName.value.trim()) {alert('请输入群组名称');return;}if (!memberList.value.trim()) {alert('请输入群成员');return;}try {const members = memberList.value.split(',').map(id => id.trim()).filter(id => id).map(userID => ({ userID }));if (members.length === 0) {alert('请输入有效的群成员ID');return;}const groupParams: CreateGroupParams = {name: groupName.value,memberList: members,type: groupType.value,};const conversation = await createGroupConversation(groupParams);setActiveConversation(conversation.conversationID);console.log('群聊创建成功:', conversation.conversationID);// 重置表单groupName.value = '';memberList.value = '';groupType.value = 'Work';} catch (error) {console.error('创建群聊失败:', error);alert('创建群聊失败,请检查参数是否正确');}};</script><style scoped>.conversation-creator {padding: 20px;max-width: 500px;}.create-c2c, .create-group {background: #f9f9f9;border-radius: 8px;padding: 20px;margin-bottom: 20px;}.create-c2c h4, .create-group h4 {margin: 0 0 16px 0;color: #333;}.form-group {display: flex;gap: 12px;margin-bottom: 16px;align-items: center;}.form-group:last-child {margin-bottom: 0;}.form-group label {min-width: 80px;font-weight: 500;}.form-group input,.form-group select,.form-group textarea {flex: 1;padding: 8px 12px;border: 1px solid #d9d9d9;border-radius: 4px;font-size: 14px;}.form-group textarea {resize: vertical;font-family: inherit;}.member-selector {display: flex;flex-direction: column;gap: 8px;margin-bottom: 16px;}.member-selector label {font-weight: 500;color: #333;}button {padding: 8px 16px;background: #1890ff;color: white;border: none;border-radius: 4px;cursor: pointer;font-size: 14px;transition: background-color 0.2s;}button:hover:not(:disabled) {background: #40a9ff;}button:disabled {background: #d9d9d9;cursor: not-allowed;}</style>
效果如图:
