mdm-im-v3
v1.2.0
Published
基于 OpenIM SDK 的 Vue 3 即时通讯组件库,提供会话列表、单聊/群聊消息、文件收发、入群审批等功能。
Readme
mdm-im-v3
基于 OpenIM SDK 的 Vue 3 即时通讯组件库,提供会话列表、单聊/群聊消息、文件收发、入群审批等功能。
技术栈
- Node 18+(推荐 Node 20+ LTS)
- Vue 3 + ElementPlus
- OpenIM client-sdk(
@openim/[email protected]) 技术文档
安装
pnpm i mdm-im-v3@latest -S本库依赖以下 peer dependencies,需在项目中自行安装:
pnpm i vue@^3.5 element-plus@^2.9 @element-plus/icons-vue@^2.3 pinia@^3.0 pinia-plugin-persist@^1.0 vue-router@^4.5 axios@^1.8 sass@^1.86 -S快速开始
方式一:autoLogin(推荐)
通过组件暴露的 autoLogin 方法一键完成初始化、登录和会话加载:
<template>
<mdm-im-v3 ref="chatRef" theme="dark" />
</template>
<script setup>
import { ref } from 'vue'
import 'mdm-im-v3/style/index.css'
import { mdmImV3 } from 'mdm-im-v3'
const chatRef = ref()
const handleLogin = () => {
chatRef.value.autoLogin({
loginCode: 'your-account', // 用户登录账号,必填
userName: 'your-name', // 用户名
imToken: 'your-im-token', // OpenIM 用户令牌,必填
satoken: 'your-system-token',// 系统 token(上传文件等接口使用)
apiUrl: 'https://your-api-url:8443', // IM api 地址,必填
imPlatform: 5, // IM 平台标识,可选,5-网页端
})
}
</script>autoLogin 内部自动完成:store 写入用户信息 → 初始化 IM SDK → 登录 → 轮询登录状态 → 状态变为已登录后拉取会话列表。
方式二:手动控制登录流程
需要更细粒度的控制时,通过 useMessage + useChatStore 手动管理:
<template>
<mdm-im-v3 ref="chatRef" theme="dark" />
</template>
<script setup>
import { ref, watch } from 'vue'
import 'mdm-im-v3/style/index.css'
import { useMessage, useChatStore } from 'mdm-im-v3/core'
import { mdmImV3 } from 'mdm-im-v3'
const chatStore = useChatStore()
const { initIMSDK } = useMessage(chatStore)
const chatRef = ref()
// 1. 写入用户信息到 store
chatStore.setUserInfo({
userID: 'your-account',
nickname: 'your-name',
imToken: 'your-im-token',
satoken: 'your-system-token',
apiUrl: 'https://your-api-url:8443',
wsUrl: 'wss://your-ws-url:8443',
})
// 2. 初始化并登录
initIMSDK().then(() => {
console.log('IM 初始化完成')
})
// 3. 监听登录状态,3 = 已登录
watch(
() => chatStore.getLoginStatus,
status => {
if (status === 3) {
chatRef.value?.afterLogged()
}
}
)
</script>组件 Props
| Prop | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| theme | String | 'dark' | 主题:'dark'(深色) / 'light'(浅色) |
| baseConfig | Object | {} | IM 配置对象,见下方说明 |
| showConversationList | Boolean | true | 是否显示左侧会话列表 |
| groupID | String | '' | 指定群组 ID,登录后直接打开该群会话 |
| loadMessageCount | Number | 50 | 每次加载的历史消息数量(范围 10–100) |
| tenantID | String\|Number | '1' | 租户 ID,随消息扩展字段发送 |
| onKeywordCheck | Boolean | false | 是否启用外部敏感词校验(开启后发送文本会触发 send-chat-text 事件) |
| outsideHandleUser | Boolean | false | 是否由外部处理人员选择(开启后邀请成员会触发 invite-member 事件) |
baseConfig 字段
| 字段 | 类型 | 说明 |
|------|------|------|
| apiUrl | String | IM API 地址,必填 |
| loginCode | String | 用户登录账号,必填 |
| imToken | String | OpenIM 用户令牌,必填 |
| userName | String | 用户名 |
| satoken | String | 系统 token |
| imPlatform | String | IM 平台标识,默认 web |
组件 Events
| 事件名 | 参数 | 说明 |
|--------|------|------|
| send-chat-text | { list, isReply, atUserList } | onKeywordCheck 为 true 时,文本发送前触发,用于外部敏感词过滤。过滤后调用 chatRef.sendCheckedText() 发送 |
| invite-member | memberIds: string[] | outsideHandleUser 为 true 时,需要邀请成员时触发,由外部处理人员选择 |
组件暴露的方法
通过 ref 调用:
autoLogin(config)
一键登录,参数对象:
{
loginCode: string // 用户登录账号,必填
userName?: string // 用户名
imToken: string // OpenIM 用户令牌,必填
satoken?: string // 系统 token
apiUrl: string // IM API 地址,必填
imPlatform?: number // IM 平台
}无返回值。方法内部完成 store 写入、SDK 初始化、登录、轮询状态直到会话列表加载完毕。
afterLogged()
IM 登录成功后调用,拉取会话列表。配合方式二使用,方式一(autoLogin)内部已自动调用。
sendCheckedText({ list, isReply, atUserList })
发送经过敏感词校验后的文本。与 send-chat-text 事件配合使用:
// 父组件中
const handleSendChatText = ({ list, isReply, atUserList }) => {
// 调用外部敏感词过滤接口...
const filteredList = keywordFilter(list)
chatRef.value.sendCheckedText({ list: filteredList, isReply, atUserList })
}inviteUser(groupID, userIDs)
邀请用户进群:
chatRef.value.inviteUser('group-id-xxx', ['user1', 'user2'])
// 返回 Promise<boolean>openGroupApplications()
打开入群申请审批抽屉(群主/管理员审批入口)。
useMessage API
从 mdm-im-v3/core 导入,用于手动管理 IM 生命周期:
import { useMessage, useChatStore } from 'mdm-im-v3/core'
const chatStore = useChatStore()
const { initIMSDK, clearInstance, getUnReadMessageCount, setConversationMsgAsRead, mittBus } = useMessage(chatStore)参数
messageStore:通过useChatStore()获取的 Pinia store 实例(必传)
返回值
| 方法/属性 | 说明 |
|-----------|------|
| initIMSDK() | 初始化 SDK → 绑定所有 OpenIM 事件 → 登录。需先在 store 中设置 userID、imToken、apiUrl 等。返回 Promise<void>。 |
| clearInstance(bool) | 解绑事件 → 登出 → 清除 SDK 实例。传入 true 时同时清空会话列表和 window.imInstance。 |
| getUnReadMessageCount(fromServer?) | 获取未读消息总数。fromServer=true 从服务端获取,默认从本地会话列表累计。 |
| setConversationMsgAsRead(conversationID?) | 将指定会话的消息标记为已读,不传则使用当前会话。窗口失焦时自动跳过。 |
| mittBus | 全局事件总线实例,用于监听 IM 自定义事件(见下方事件列表) |
ChatStore
通过 useChatStore() 获取,是 Pinia store(id: 'chatMessage'),已开启 localStorage 持久化,持久化字段包括:userID、nickname、faceURL、platformID、imToken、satoken、apiUrl、wsUrl、tenantID。
常用 State
| 字段 | 说明 |
|------|------|
| loginStatus | 登录状态:1-未登录,2-登录中,3-已登录 |
| userID | 当前用户 ID |
| nickname | 用户昵称 |
| imToken | IM 令牌 |
| unReadCount | 未读消息总数 |
| isFocused | 窗口是否聚焦 |
常用 Getters
| Getter | 说明 |
|--------|------|
| getLoginStatus | 获取登录状态 |
| getUserInfo | 获取用户完整信息对象 |
| getBaseUrl | 获取 API 地址 |
| getUnReadCount | 获取未读总数 |
| getIsFocused | 获取窗口聚焦状态 |
常用 Actions
| Action | 说明 |
|--------|------|
| setUserInfo(obj) | 合并写入用户信息 |
| setLoginStatus(val) | 设置登录状态 |
| setUnReadCount(count) | 设置未读消息数 |
| setIsFocused(bool) | 设置窗口聚焦状态 |
MittBus 事件
通过 useMessage(store).mittBus 获取,可监听以下 IM 自定义事件:
| 事件名 | 说明 |
|--------|------|
| createSLRemote | 远程桌面连接已创建,携带 { address, session } |
| applySLControl | 收到远程控制申请,携带 { sendUserName, sendUserID, recvUserID } |
| acceptSLControl | 远程控制申请被接受 |
| rejectSLControl | 远程控制申请被拒绝 |
| inviteSLControl | 被邀请远程控制 |
| acceptSLRemote | 远程桌面被接受 |
| rejectSLRemote | 远程桌面被拒绝 |
| LOGOUT_NOTICE | 账号在其他设备登录,被强制下线 |
| IM_LOGOUT | IM 已登出 |
| OnGroupInfoChanged | 群信息变更(名称、头像、公告等) |
| OnJoinedGroupAdded | 被拉入新群 |
| OnJoinedGroupDeleted | 退出或被踢出群 |
| OnGroupMemberDeleted | 群成员减少(退群/被踢) |
| OnGroupApplicationAdded | 收到新的入群申请 |
| OnGroupApplicationAccepted | 入群申请被同意 |
| OnGroupApplicationRejected | 入群申请被拒绝 |
监听示例:
const { mittBus } = useMessage(chatStore)
mittBus.on('LOGOUT_NOTICE', () => {
// 处理被强制下线
router.push('/login')
})主题
支持深色(dark)和浅色(light)两套主题,通过 CSS 变量驱动:
<!-- 深色主题 -->
<mdm-im-v3 theme="dark" />
<!-- 浅色主题 -->
<mdm-im-v3 theme="light" />主题 CSS 变量定义在 chat-dark-theme / chat-light-theme 类名下,可通过覆盖 CSS 变量进行自定义。
