UniApp 集成腾讯云IM实现@功能的实战指南
一、技术选型与实现目标
在社交类应用开发中,群聊@功能是提升沟通效率的核心交互。本文将基于腾讯云IM SDK,在UniApp框架下实现以下功能:
- 消息输入时智能提示@对象
- 发送消息时携带@成员信息
- 接收端精准识别@内容并高亮显示
- 被@用户接收实时通知提醒
二、环境准备与SDK初始化
2.1 安装依赖包
npm install tim-js-sdk tim-upload-plugin --save
2.2 全局SDK配置
// main.js
import TIM from 'tim-js-sdk';
import TIMUploadPlugin from 'tim-upload-plugin';
// 创建SDK实例
export const tim = TIM.create({
SDKAppID: xxxxxxxxxxx // 必填项
});
// 注册上传插件
tim.registerPlugin({ 'tim-upload-plugin': TIMUploadPlugin });
// 初始化配置
tim.setLogLevel(0); // 调试阶段建议开启日志
三、核心功能实现流程
3.1 消息构造器封装
// utils/message-builder.js
export const buildAtMessage = (content, atUserList = []) => {
return {
type: 'TIMTextElem',
content: {
text: content,
mentionInfo: {
mentionedType: atUserList.length ? 'PART' : 'ALL',
mentionedUserList: atUserList.map(user => ({
userID: user.userID,
nickName: user.nickName || ''
}))
}
}
};
};
3.2 发送带@的消息
// pages/chat/chat.vue
async function handleSendMessage() {
if (!this.messageContent.trim()) return;
try {
const message = tim.createTextMessage({
to: this.currentConversation.groupId,
conversationType: 'GROUP',
payload: buildAtMessage(
this.messageContent,
this.selectedAtUsers // 存储已选@用户的数组
)
});
const { data: messageID } = await tim.sendMessage(message);
console.log('消息发送成功', messageID);
} catch (err) {
console.error('发送失败:', err);
uni.showToast({ title: '发送失败', icon: 'none' });
}
}
3.3 消息接收与解析
// 消息监听逻辑
tim.on(TIM.EVENT.MESSAGE_RECEIVED, (event) => {
event.data.forEach(message => {
if (message.type === 'TIMTextElem') {
handleTextMessage(message);
}
});
});
function handleTextMessage(message) {
const { mentionInfo } = message.payload;
if (!mentionInfo) return;
// 判断是否包含当前用户
const isMentioned = mentionInfo.mentionedUserList.some(user =>
user.userID === tim.getUserProfile().userID
);
if (isMentioned) {
// 触发本地通知(需实现具体逻辑)
showLocalNotification(message);
}
}
3.4 前端UI高亮渲染
<template>
<view class="message-container">
<rich-text :nodes="parseMessageContent(message.payload.text)"></rich-text>
</view>
</template>
<script>
export default {
methods: {
parseMessageContent(text) {
const atPattern = /@(\S+?)\b/g;
const segments = [];
let lastIndex = 0;
text.replace(atPattern, (match, p1, offset) => {
// 添加普通文本
if (offset > lastIndex) {
segments.push({ type: 'text', text: text.slice(lastIndex, offset) });
}
// 添加@标记
segments.push({
type: 'span',
attrs: {
class: 'at-mention',
'@click': `handleAtClick('${p1}')`
},
children: [{ type: 'text', text: match }]
});
lastIndex = offset + match.length;
return '';
});
// 处理剩余文本
if (lastIndex < text.length) {
segments.push({ type: 'text', text: text.slice(lastIndex) });
}
return segments;
}
}
}
</script>
<style>
.at-mention {
color: #007AFF;
font-weight: 500;
padding: 2rpx 4rpx;
border-radius: 4rpx;
background-color: rgba(0,122,255,0.1);
}
</style>
四、关键优化策略
4.1 输入框@联想优化
<!--使用uni-popup实现选择器-->
<uni-popup ref="atSelector" type="bottom">
<scroll-view scroll-y style="max-height: 60vh">
<view
v-for="user in filteredUsers"
:key="user.userID"
class="at-item"
@click="selectAtUser(user)"
>
{{ user.nickName }}
</view>
</scroll-view>
</uni-popup>
<script>
export default {
methods: {
handleInput(e) {
const content = e.detail.value;
const lastWord = content.split(/[\s@]/).pop();
if (lastWord.startsWith('@')) {
const keyword = lastWord.slice(1);
this.searchUsers(keyword);
}
}
}
}
</script>
4.2 消息防抖处理
// 使用lodash防抖优化输入体验
import _ from 'lodash';
export default {
methods: {
handleInput: _.debounce(function(e) {
// 原始处理逻辑
}, 300)
}
}
五、生产环境注意事项
-
安全校验:
- 后端应校验@用户是否属于当前群组
- 限制单条消息@人数(建议不超过50人)
-
性能优化:
// 消息内容长度限制 const MAX_MESSAGE_LENGTH = 2000; if (text.length > MAX_MESSAGE_LENGTH) { uni.showToast({ title: '消息内容过长', icon: 'none' }); return; }
-
平台适配:
- 小程序端需处理rich-text组件对span标签的支持
- App端建议使用原生富文本组件提升渲染性能
-
扩展功能建议:
// @所有人特殊处理 if (atUsers.includes('ALL')) { // 显示红色醒目标记 // 触发强制推送通知 }
六、总结
通过腾讯云IM的自定义消息机制,结合UniApp的跨平台能力,可以高效实现完整的@功能体系。实际开发中需重点关注:
- 消息协议的规范设计(推荐使用JSON Schema校验)
- 前后端数据校验的闭环机制
- 输入体验的持续优化(建议接入Fuse.js实现模糊搜索)
- 性能监控(重点关注消息渲染时的DOM节点数量)