mdm-im-v3

中文文档
2.1.3发布于 2026/11/04MITES Module

基于 OpenIM SDK 的 Vue 3 即时通讯组件库,提供会话列表、单聊/群聊消息、文件收发、入群审批等功能。同时支持 PC 端(Element-Plus)和 H5 移动端(Vant 4),打包后通过 npm 分发,由同一包提供双端组件。

中文使用文档
文档目录44 节
  1. 技术栈
  2. npm 包目录结构
  3. 导入路径映射
  4. 安装
  5. 安装 peer 依赖
  6. PC 端使用
  7. 方式一:autoLogin(推荐)
  8. 方式二:手动控制登录流程(分步加载)
  9. H5 移动端使用
  10. 前置准备
  11. 入口文件(main.js)
  12. 根组件(App.vue)
  13. 方式一:autoLogin(推荐)
  14. 方式二:分步加载(手动控制登录流程)
  15. H5 内置路由表
  16. H5 组件 Props
  17. H5 组件暴露的方法
  18. H5 端与 PC 端差异
  19. 组件 Props
  20. baseConfig 字段
  21. 组件 Events
  22. unread-change (未读消息数)
  23. 组件暴露的方法
  24. autoLogin(config)
  25. checkLogin()
  26. sendCheckedText({ list, isReply, atUserList })
  27. inviteUser(groupID, userIDs)
  28. useMessage API
  29. 参数
  30. 返回值
  31. ChatStore
  32. 常用 State
  33. 常用 Getters
  34. 常用 Actions
  35. MittBus 事件
  36. 阅后即焚(Burn After Reading)
  37. 使用入口
  38. 规则
  39. 服务端能力与限制
  40. 语音消息(Voice Message)
  41. 使用入口
  42. 录音与发送规格
  43. 依赖与权限
  44. 主题

mdm-im-v3

基于 OpenIM SDK 的 Vue 3 即时通讯组件库,提供会话列表、单聊/群聊消息、文件收发、入群审批等功能。同时支持 PC 端(Element-Plus)和 H5 移动端(Vant 4),打包后通过 npm 分发,由同一包提供双端组件。

技术栈

  • Node 18+(推荐 Node 20+ LTS)
  • Vue 3 + Pinia + vue-router
  • OpenIM client-sdk(@openim/[email protected]) 技术文档
  • PC 端:Element-Plus / H5 端:Vant 4

npm 包目录结构

安装 mdm-im-v3 后,node_modules 中的包目录如下:

node_modules/mdm-im-v3/
├── dist/                            # PC 端构建产物
│   ├── index.es.js                  #   入口(导出 mdmImV3 组件)
│   ├── core.es.js                   #   入口(导出 useMessage + useChatStore)
│   ├── style/index.css              #   样式文件
│   ├── index-*.js                   #   内部代码分割文件(Vite 自动分包)
│   ├── wangeditor-*.js              #   富文本编辑器分包
│   ├── vue-office-*.js              #   文档预览分包
│   └── assets/                      #   图片/字体等资源文件
├── dist-h5/                         # H5 端构建产物
│   ├── index.es.js                  #   入口(导出 mdmImV3H5 组件,内部自带路由)
│   ├── style/index-h5.css           #   样式文件
│   ├── *H5-*.js                     #   按路由拆分的页面代码
│   └── assets/                      #   图片/字体等资源文件
├── package.json                     # package exports 定义导入路径映射
└── README.md

导入路径映射

package.json 的 exports 字段定义了以下导入路径,消费方使用路径名导入即可,无需关心内部目录结构:

导入路径对应文件导出内容用途
mdm-im-v3dist/index.es.jsmdmImV3PC 端主组件
mdm-im-v3/coredist/core.es.jsuseMessage, useChatStoreIM 登录/通信核心(PC/H5 通用)
mdm-im-v3/h5dist-h5/index.es.jsmdmImV3H5H5 端主组件(内部自带路由)
mdm-im-v3/style/index.cssdist/style/index.cssCSSPC 端样式文件
mdm-im-v3/style/index-h5.cssdist-h5/style/index-h5.cssCSSH5 端样式文件

核心原则: mdm-im-v3/core 在两端通用,PC 端额外导入 mdm-im-v3(组件)和 mdm-im-v3/style/index.css(样式),H5 端额外导入 mdm-im-v3/h5(组件)和 mdm-im-v3/style/index-h5.css(样式)。

图标字体已内置: 两个样式文件都包含 @font-face 与全部 .mdm-icon-* 类(字体文件随包输出到 dist/assets/extracted/、dist-h5/assets/extracted/),消费方无需再单独引入 iconfont.css,也不依赖宿主是否已有同名图标字体。

安装

pnpm i mdm-im-v3@latest -S

安装 peer 依赖

PC 端 需安装以下依赖(选择你自己的包管理器):

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

H5 端 同样需要安装 Vue 等基础依赖,但无需安装 element-plus,改为安装 Vant:

# H5 端需要的基础依赖(与 PC 端共享 pinia、vue-router、sass 等)
pnpm i vue@^3.5 pinia@^3.0 pinia-plugin-persist@^1.0 vue-router@^4.5 axios@^1.8 sass@^1.86 -S

# H5 端额外需要 Vant
pnpm i vant@^4.10 -S

H5 端不需要安装 element-plus 和 @element-plus/icons-vue。


PC 端使用

方式一: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 地址,必填
    platformID: 5,           // IM 平台标识,可选,5-网页端
  })
}
</script>

autoLogin 内部自动完成:store 写入用户信息 → 初始化 IM SDK → 登录 → 轮询登录状态 → 状态变为已登录后拉取会话列表。

方式二:手动控制登录流程(分步加载)

适用于先登录 IM 获取未读数 → 再切换到 IM 页面展示内容的场景:

完整说明与可运行示例见 获取即时消息组件mdm-im-v3的未读消息数量的调用方式.md。

  1. 入口处调用 useMessage(config) 初始化 IM,获取未读数量
  2. 用户切换到 IM 菜单时再渲染 <mdm-im-v3> 组件
  3. 组件自动读取 store 中的已登录状态和 window.imInstance,无需重复初始化
// ========== 步骤1:应用入口处登录 IM ==========
import { watch } from 'vue'
import { useMessage } from 'mdm-im-v3/core'

const { initIMSDK, getUnReadMessageCount, loginStatus, messageStore } = useMessage({
  userID: 'your-account',        // 用户 ID,必填
  nickname: 'your-name',          // 用户昵称
  faceURL: '',                    // 用户头像
  imToken: 'your-im-token',       // OpenIM 用户令牌,必填
  satoken: 'your-system-token',   // 系统 token
  apiUrl: 'https://your-api-url:8443',  // IM API 地址,必填
  wsUrl: 'wss://your-ws-url:8443',      // IM WebSocket 地址
  tenantID: '',                   // 租户 ID
  platformID: 5,                  // 平台标识,5-网页端
})

// 初始化并登录
await initIMSDK()

// 监控 IM 登录状态,登录成功后获取未读数
watch(loginStatus, status => {
  if (status === 3) {
    getUnReadMessageCount(true)
  }
})
<!-- ========== 步骤2:切换菜单后渲染 PC 组件 ========== -->
<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'
// 组件会自动读取 store 和 window.imInstance,无需再次初始化

const chatRef = ref()
</script>

原理: useMessage() 内部自动将配置存入 Pinia store(useChatStore),initIMSDK() 创建的 IM 实例挂载到 window.imInstance。 组件挂载时检测到 loginStatus === 3(已登录),直接复用已有的 IM 实例和会话数据,无需二次登录。


H5 移动端使用

本库同时提供 H5 移动端组件,基于 Vant 4 UI 库构建,采用独立全屏页面路由(区别于 PC 端左右分栏布局)。H5 端从 mdm-im-v3/h5 路径导入组件,与 PC 端一样,只需要一个入口组件,无需暴露路由。

前置准备

H5 端需要安装 Vant 并在入口文件中注册:

pnpm i vant@^4.10 -S

入口文件(main.js)

import { createApp } from 'vue'
import { createPinia } from 'pinia'
import PiniaPersist from 'pinia-plugin-persist'
import Vant from 'vant'
import 'vant/lib/index.css'
import 'mdm-im-v3/style/index-h5.css'
import { mdmImV3H5 } from 'mdm-im-v3/h5'

import App from './App.vue'

const app = createApp(App)
const pinia = createPinia()
pinia.use(PiniaPersist)

app.use(pinia)
app.use(Vant)
app.mount('#app')

注意: H5 路由使用 createWebHashHistory,共有 11 个页面路径,全部内聚在 mdmImV3H5 组件内部,消费方无需注册路由,只需在模板中放置 <mdm-im-v3-h5> 标签即可。

根组件(App.vue)

<template>
  <mdm-im-v3-h5 ref="h5Ref" theme="light" />
</template>

<script setup>
import { ref } from 'vue'
import { mdmImV3H5 } from 'mdm-im-v3/h5'

const h5Ref = ref()
</script>

方式一:autoLogin(推荐)

通过组件暴露的 autoLogin 方法一键完成初始化、登录和会话加载,与 PC 端完全一致:

<template>
  <mdm-im-v3-h5 ref="h5Ref" theme="light" />
</template>

<script setup>
import { ref } from 'vue'
import { mdmImV3H5 } from 'mdm-im-v3/h5'

const h5Ref = ref()

const handleLogin = () => {
  h5Ref.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 地址,必填
    platformID: 5,               // IM 平台标识,可选,5-网页端
  })
}
</script>

autoLogin 内部自动完成:store 写入用户信息 → 初始化 IM SDK → 登录 → 轮询登录状态 → 状态变为已登录后自动跳转到会话列表页。

方式二:分步加载(手动控制登录流程)

适用于先登录 IM 获取未读数 → 再切换到 IM 页面展示内容的场景,与 PC 端流程一致:

// ========== 步骤1:应用入口处登录 IM ==========
import { watch } from 'vue'
import { useMessage } from 'mdm-im-v3/core'

const { initIMSDK, getUnReadMessageCount, loginStatus } = useMessage({
  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',
  platformID: 5,
})

// 初始化并登录
await initIMSDK()

// 监控 IM 登录状态,登录成功后获取未读数
watch(loginStatus, status => {
  if (status === 3) {
    getUnReadMessageCount(true)
  }
})
<!-- ========== 步骤2:切换菜单后渲染 H5 组件 ========== -->
<template>
  <mdm-im-v3-h5 ref="h5Ref" theme="light" />
</template>

<script setup>
import { ref } from 'vue'
import { mdmImV3H5 } from 'mdm-im-v3/h5'
// 组件会自动读取 store 和 window.imInstance,无需再次初始化

const h5Ref = ref()
</script>

原理: useMessage() 内部自动将配置存入 Pinia store(useChatStore),initIMSDK() 创建的 IM 实例挂载到 window.imInstance。<mdm-im-v3-h5> 组件挂载时检测到 loginStatus === 3(已登录),直接复用已有的 IM 实例和会话数据,无需二次登录。

H5 内置路由表

以下路由全部内聚在 mdmImV3H5 组件内部,消费方无需关心:

路径组件说明
/会话列表主页展示会话列表,支持滑动操作
/chat聊天页消息列表 + 文字/图片/文件输入
/search搜索页搜索用户和本地会话
/notice群通知入群申请审批列表
/create-group创建群组选择成员创建群聊
/select-members选择成员通用人员选择器
/member-detail人员详情单聊/群成员信息卡片
/chat-settings聊天设置免打扰/清聊天记录/退出群聊
/group-announcement群公告查看/编辑群公告
/chat-history聊天记录按日期查看历史消息
/group-members群成员列表展示/管理群成员

H5 组件 Props

Prop类型默认值说明
themeString'light'主题:'dark' / 'light'
baseConfigObject{}IM 配置对象
groupIDString''指定群组 ID,登录后直接打开该群
loadMessageCountNumber50每次加载的历史消息数量(10–100)
tenantIDString|Number'1'租户 ID
onKeywordCheckBooleanfalse是否启用外部敏感词校验
outsideHandleUserBooleanfalse是否由外部处理人员选择

H5 组件暴露的方法

通过 ref 调用 <mdm-im-v3-h5>:

// autoLogin — 一键登录
h5Ref.value.autoLogin({
  loginCode: string    // 用户登录账号,必填
  userName?: string    // 用户名
  imToken: string      // OpenIM 用户令牌,必填
  satoken?: string     // 系统 token
  apiUrl: string       // IM API 地址,必填
  platformID?: number  // IM 平台标识(默认 5-网页端)
})

// checkLogin() — 检测 store 中已有登录状态后跳转到会话列表页
h5Ref.value.checkLogin()

H5 组件同样支持 unread-change 事件(参数与 PC 端一致,见 组件 Events),宿主可通过 @unread-change 监听未读消息数变化。

H5 端与 PC 端差异

维度PCH5
导入路径mdm-im-v3mdm-im-v3/h5
导入内容mdmImV3(组件)mdmImV3H5(组件)
核心库mdm-im-v3/coremdm-im-v3/core(共享)
样式入口mdm-im-v3/style/index.cssmdm-im-v3/style/index-h5.css
UI 库Element-PlusVant 4
布局左右分栏(会话列表 + 聊天面板同屏)独立全屏页面,路由导航
路由无内置路由,消费方自行管理内置路由(hash 模式,11 页面),内聚在组件内部
消息输入富文本编辑器(@wangeditor)纯文本 <textarea>
会话操作右键 contextmenu 菜单左滑操作 + 长按 ActionSheet
截图支持 js-web-screen-shot不支持
下拉刷新/无限滚动自定义滚动事件van-pull-refresh + van-list

组件 Props

Prop类型默认值说明
themeString'dark'主题:'dark'(深色) / 'light'(浅色)
baseConfigObject{}IM 配置对象,见下方说明
showConversationListBooleantrue是否显示左侧会话列表(仅 PC 端有效)
groupIDString''指定群组 ID,登录后直接打开该群会话
loadMessageCountNumber50每次加载的历史消息数量(范围 10–100)
tenantIDString|Number'1'租户 ID,随消息扩展字段发送
onKeywordCheckBooleanfalse是否启用外部敏感词校验(开启后发送文本会触发 send-chat-text 事件)
outsideHandleUserBooleanfalse是否由外部处理人员选择(开启后邀请成员会触发 invite-member 事件)

baseConfig 字段

字段类型说明
apiUrlStringIM API 地址,必填
loginCodeString用户登录账号,必填
imTokenStringOpenIM 用户令牌,必填
userNameString用户名
satokenString系统 token
platformIDStringIM 平台标识,默认 web

组件 Events

PC 与 H5 组件支持相同的事件:

事件名参数说明
send-chat-text{ list, isReply, atUserList }onKeywordCheck 为 true 时,文本发送前触发,用于外部敏感词过滤。过滤后调用 chatRef.sendCheckedText() 发送
invite-membermemberIds: string[]outsideHandleUser 为 true 时,需要邀请成员时触发,由外部处理人员选择
unread-change{ count, reason, time, conversationID? }IM 未读消息总数变化时触发,可用于同步宿主的消息红点/角标,见下方说明

unread-change(未读消息数)

组件在以下时机向上抛出该事件:

reason触发时机
'init'IM 初始化加载完成(登录后会话列表拉取/缓存渲染结束),每次初始化触发一次
'receive'收到新消息(SDK 每批推送触发一次,即使未读总数没变)
'update'未读总数发生变化,如标记已读、其他端已读、新会话等

事件载荷:

{
  count: number          // 当前未读消息总数
  reason: 'init' | 'receive' | 'update'
  time: number           // 触发时间戳(毫秒)
  conversationID?: string // 仅 reason='receive':最新消息所属会话 ID
}

PC / H5 用法一致:

<template>
  <mdm-im-v3 ref="chatRef" @unread-change="handleUnreadChange" />
  <!-- H5:<mdm-im-v3-h5 ref="chatRef" @unread-change="handleUnreadChange" /> -->
</template>

<script setup>
const handleUnreadChange = ({ count, reason, conversationID }) => {
  // 同步宿主菜单/标签页的红点数量
  badgeRef.value = count
  console.log('[IM] 未读数:', count, reason, conversationID)
}
</script>

未读总数同时保存在 store 的 unReadCount 中,可通过 useChatStore().getUnReadCount 读取;unread-change 事件适用于不便订阅 store 的宿主(如非 Vue 渲染的菜单/角标)。

组件暴露的方法

通过 ref 调用:

autoLogin(config)

一键登录,参数对象:

{
  loginCode: string   // 用户登录账号,必填
  userName?: string   // 用户名
  imToken: string     // OpenIM 用户令牌,必填
  satoken?: string    // 系统 token
  apiUrl: string      // IM API 地址,必填
  platformID?: number // IM 平台
}

无返回值。方法内部完成 store 写入、SDK 初始化、登录、轮询状态直到会话列表加载完毕。

checkLogin()

轮询检测登录状态:当 store 中 loginStatus === 3(已登录)且 window.imInstance 存在时,自动调用内部 afterLogged() 拉取会话列表。配合方式二(手动 useMessage 登录)使用;方式一(autoLogin)内部已自动调用。

注:afterLogged() 为组件内部方法,未通过 defineExpose 暴露,外部请调用 checkLogin() 触发会话加载。

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>

useMessage API

从 mdm-im-v3/core 导入,PC / H5 两端通用,用于手动管理 IM 生命周期:

import { useMessage, useChatStore } from 'mdm-im-v3/core'

const { initIMSDK, clearInstance, getUnReadMessageCount, setConversationMsgAsRead, mittBus } = useMessage({
  userID: 'your-account',
  nickname: 'your-name',
  faceURL: '',
  imToken: 'your-im-token',
  satoken: 'your-system-token',
  apiUrl: 'https://your-api-url:8443',
  wsUrl: 'wss://your-ws-url:8443',
  tenantID: '',
  platformID: 5,
})

参数

useMessage(config?) 接收一个可选的配置对象,所有字段均为可选:

字段类型说明
userIDString用户 ID
nicknameString用户昵称
faceURLString用户头像
imTokenStringOpenIM 用户令牌
satokenString系统 token
apiUrlStringIM API 地址
wsUrlStringIM WebSocket 地址
tenantIDString租户 ID
platformIDNumberIM 平台标识,5-网页端

传入配置后,useMessage 内部立刻调用 chatStore.setUserInfo() 将参数保存到 Pinia store。也可以不传参数,后续在调用 initIMSDK() 前手动写入 store。

返回值

方法/属性说明
messageStorePinia store 实例(useChatStore()),可直接访问所有 state/getters/actions
loginStatusIM 登录状态的 computed 引用,便于外部 watch 监控。值:1-未登录,2-登录中,3-已登录
initIMSDK()初始化 SDK → 绑定所有 OpenIM 事件 → 登录。需先在 store 中设置 userID、imToken、apiUrl 等。返回 Promise<void>。
clearInstance(bool)解绑事件 → 登出 → 清除 SDK 实例。传入 true 时同时清空会话列表和 window.imInstance。
getUnReadMessageCount(fromServer?)获取未读消息总数。fromServer=true 从服务端获取,默认从本地会话列表累计。总数变化时会广播 IM_UNREAD_COUNT_CHANGED(组件转发为 unread-change 事件)。
publishUnreadCount(reason?, extra?)主动向宿主广播一次未读总数,通过 IM_UNREAD_COUNT_CHANGED 发给组件并转发为 unread-change 事件。reason 默认 'update',组件初始化完成时内部使用 'init'。
waitForSyncFinish(timeout?)等待登录后的服务端同步(OnSyncServerFinish)完成,返回 Promise<boolean>。同步完成前 SDK 本地会话缓存为空,此时拉取会话列表只会得到空数组,因此拉取会话列表前应先等待该方法;默认超时 8000ms,超时返回 false,按兜底流程继续。
setConversationMsgAsRead(conversationID?)将指定会话的消息标记为已读,不传则使用当前会话。窗口失焦时自动跳过。
mittBus全局事件总线实例,用于监听 IM 自定义事件(见下方事件列表)

ChatStore

从 mdm-im-v3/core 导入 useChatStore 后调用获取,是 Pinia store(id: 'chatMessage'),已开启 localStorage 持久化,持久化字段包括:userID、nickname、faceURL、platformID、apiUrl、wsUrl、tenantID(imToken 和 satoken 仅保存在 Pinia 内存中,不持久化到本地存储)。

import { useChatStore } from 'mdm-im-v3/core'
const chatStore = useChatStore()

常用 State

字段说明
loginStatus登录状态:1-未登录,2-登录中,3-已登录
userID当前用户 ID
nickname用户昵称
imTokenIM 令牌
unReadCount未读消息总数
isFocused窗口是否聚焦

常用 Getters

Getter说明
getLoginStatus获取登录状态
getUserInfo获取用户完整信息对象
getBaseUrl获取 API 地址
getUnReadCount获取未读总数
getIsFocused获取窗口聚焦状态

常用 Actions

Action说明
setUserInfo(obj)合并写入用户信息
setLoginStatus(val)设置登录状态
setUnReadCount(count)设置未读消息数
setIsFocused(bool)设置窗口聚焦状态

MittBus 事件

通过 useMessage().mittBus 获取,可监听以下 IM 自定义事件:

事件名说明
createSLRemote远程桌面连接已创建,携带 { address, session }
applySLControl收到远程控制申请,携带 { sendUserName, sendUserID, recvUserID }
acceptSLControl远程控制申请被接受
rejectSLControl远程控制申请被拒绝
inviteSLControl被邀请远程控制
acceptSLRemote远程桌面被接受
rejectSLRemote远程桌面被拒绝
LOGOUT_NOTICE账号在其他设备登录,被强制下线
IM_LOGOUTIM 已登出
IM_SYNC_SERVER_FINISH登录后的服务端同步结束(参数 true-成功,false-失败)。此时会话/消息缓存才就绪,可用于登录后补拉会话列表
IM_UNREAD_COUNT_CHANGED未读消息总数变化,参数 { count, reason, time, conversationID? }。组件内部据此转发 unread-change 事件,一般无需直接监听
OnGroupInfoChanged群信息变更(名称、头像、公告等)
OnJoinedGroupAdded被拉入新群
OnJoinedGroupDeleted退出或被踢出群
OnGroupMemberDeleted群成员减少(退群/被踢)
OnGroupApplicationAdded收到新的入群申请
OnGroupApplicationAccepted入群申请被同意
OnGroupApplicationRejected入群申请被拒绝

监听示例:

const { mittBus } = useMessage()
mittBus.on('LOGOUT_NOTICE', () => {
  router.push('/login')
})

阅后即焚(Burn After Reading)

单聊会话支持「阅后即焚」:谁开启,谁发送的消息才会在被对方阅读后倒计时并销毁;对方未开启时,其发送的消息不受影响。

使用入口

  • PC:聊天窗口右上角「设置」抽屉 → 单聊会话 → 「阅后即焚」开关 + 「阅后即焚时间」;
  • H5:聊天设置页(/chat-settings)→ 单聊会话 → 「阅后即焚」开关 + 时间选择。

群聊不提供该入口(OpenIM 的 isPrivateChat 语义按私密会话设计,本期仅支持单聊)。

规则

项说明
按用户持久化开关、时长、开启人、目标人写入自己会话的 ex.burn:{ enabled, duration, fromUserID, toUserID, updatedAt };ex 由服务端按用户存储,换设备/清缓存后可恢复,且不会改动对方设置
ex 兼容写入 burn 时自动 merge,保留 isHidden / isDeleted / isRead 等业务标记;这些业务写 ex 时也会用 preserveBurnInEx() 保留 burn
会话标识开启后自己的会话列表对应会话显示 🔥(按 ex.burn.fromUserID === 当前用户 判断,对方列表不会显示)
消息快照开启方发送消息时在消息 ex 写入 { burnBySender, burnDuration, burnFromUserID, burnToUserID };未开启方发送的消息不带该标记,因此不会被焚毁
时长范围1–86400 秒,默认 30 秒;PC 提供预设(10s/30s/1min/5min/30min/1h)+ 自定义
提交方式开关、时长与 ex.burn 一次性提交 setConversation(),避免"开关开了但时长为 0、消息不销毁"
关闭删除 ex.burn,后续发送的消息不再带焚毁快照;已进入倒计时的消息按原快照走完
展示带焚毁快照的消息在消息列表显示 🔥 与剩余秒数(通知类消息不展示、不参与焚毁)
通知文案1701 通知带上操作人:张三 开启了阅后即焚 / 张三 关闭了阅后即焚(自己操作显示"你")
销毁触发接收方打开会话、未读转已读后开始倒计时;发送方在收到已读回执后开始
销毁执行倒计时结束:消息列表移除 + IndexedDB 缓存回写 + deleteMessage 删除;已切换走的会话也会在后台到点删除

服务端能力与限制

  • 设置依赖服务端对会话 ex 的持久化(本项目已用于隐藏/标记未读,属于既有能力);
  • 阅后即焚的「到期真删」属于 OpenIM 服务端能力,落地前需确认当前部署版本支持;即使服务端不支持,组件仍会按本地倒计时把消息从界面与缓存中移除(弱一致);
  • 服务端会话上的 isPrivateChat / burnDuration 仍会随设置同步(用于 1701 通知与 SDK 私密快照),但组件不再据此决定是否焚毁。

相关字段:会话 ex.burn(设置,按用户);消息 ex.burnBySender / burnDuration / burnFromUserID / burnToUserID(发送方快照,组件焚毁依据);attachedInfoElem 仅作兼容展示。

语音消息(Voice Message)

支持在 PC / H5 端录制并发送 OpenIM 语音消息(contentType = 103,soundElem),消息列表复用已有语音气泡(时长 + 声波 + 播放)。

使用入口

  • H5:输入区左侧「语音/键盘」切换按钮 → 按住「按住 说话」开始录音,松开发送;上滑超过 80px 松开取消;
  • PC:编辑器工具栏麦克风图标 → 录音弹窗 → 点击麦克风开始,点击「停止并发送」结束并发送;
  • 另:PC 选择/拖拽音频文件、H5 选择音频文件,都会按语音消息发送(不再显示成文件卡片)。

录音与发送规格

项说明
录音格式WAV(PCM),16kHz / 16bit / 单声道,全平台可播放
时长最短 1 秒(太短提示"录音时间太短"),最长 60 秒(最后 10 秒倒计时,到点自动发送)
发送链路先上传业务文件服务(/api/v1/common/uploadFiles)→ createSoundMessageByURL → 乐观插入 → sendMessageNotOss
时长取值优先读音频元数据(getMediaDuration),其次录音器计时,最后按实际耗时兜底;存储为整秒且 ≥1
失败处理上传失败不产生消息;发送失败气泡标记 status=3(红色感叹号)
播放复用 useAudioPlayer,录音开始会暂停正在播放的语音,避免外放混入
后台切换录音中切到后台/隐藏页面自动取消,避免后台持续录音

依赖与权限

  • 录音依赖 js-audio-recorder(已加入 dependencies),产物为 WAV,iOS / 微信浏览器 / Electron 均可播放;
  • 浏览器录音要求 HTTPS 或 localhost,首次使用需授权麦克风;拒绝授权、无麦克风、浏览器不支持时均有 Toast 提示;
  • PC Electron 需在系统层允许麦克风权限。

相关字段:soundElem.duration(秒,必填)、sourceUrl / soundPath(播放地址,组件会补 baseUrl 并把 /api/v1/common/reviewFile/ 重写为 /api/v1/auth/reviewFile/)、dataSize、soundType(如 wav)。

主题

支持深色(dark)和浅色(light)两套主题,通过 CSS 变量驱动:

<mdm-im-v3 theme="dark" />
<mdm-im-v3 theme="light" />

主题 CSS 变量定义在 chat-dark-theme / chat-light-theme 类名下,可通过覆盖 CSS 变量进行自定义。

版本与发布记录

mdm-im-v3 共发布 20 个版本,首次发布于 2025/10/30;过去 12 个月发布了 19 个版本。

版本发布日期距今
2.1.3latest2026/11/04今天
2.1.22026/11/031 天前
2.1.12026/11/031 天前
2.1.02026/11/022 天前
2.0.32026/08/182 个月前
2.0.22026/08/172 个月前

关于 mdm-im-v3 的常见问题

mdm-im-v3 是什么?

基于 OpenIM SDK 的 Vue 3 即时通讯组件库,提供会话列表、单聊/群聊消息、文件收发、入群审批等功能。同时支持 PC 端(Element-Plus)和 H5 移动端(Vant 4),打包后通过 npm 分发,由同一包提供双端组件。

如何安装 mdm-im-v3?

在项目目录运行 npm install mdm-im-v3,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:vue(^3.5.21)、sass(^1.86.3)、vant(^4.10.0)、axios(^1.8.4)、pinia(^3.0.2)、vue-router(^4.5.0)、element-plus(^2.9.7)、pinia-plugin-persist(^1.0.0)、@element-plus/icons-vue(^2.3.1)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

mdm-im-v3 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/mdm-im-v3 是否存在。

mdm-im-v3 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

mdm-im-v3 可以商用吗?

mdm-im-v3 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

mdm-im-v3 还在维护吗?

最新版本 2.1.3 发布于 2026/11/04(今天);至今共发布 20 个版本,其中过去 12 个月发布了 19 个;首次发布于 2025/10/30。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。