快速集成 uni-app 源码(Vue 3)
更新时间: 2024/09/19 16:18:40
IM uni-app Demo 是基于网易云信 IM UIKit(NEUIKit)的一款 uni-app Demo,托管在 GitHub 开源代码仓库 nim-uikit-uniapp。该 Demo 提供了一些通用的功能,包含会话、聊天、群组等,您可以基于源码搭建您的即时通讯业务逻辑。
效果预览
IM uni-app Demo 的部分界面效果如下:
平台支持
当前 IM uni-app Demo 支持:Android、iOS、H5、小程序。
前提条件
开始跑通 Demo 之前,请确保您已完成了以下操作:
-
注册 IM 账号,获取账号 ID 和 token。
-
调整本地开发环境,并满足如下要求:
配置项 要求 集成开发环境 HBuilderX Vue.js 版本 Vue 3 开发语言 TypeScript CSS 预处理器 Sass(Sass-loader 版本 <= 10.1.1) Node.js 版本 12.13.0 ~ 17.0.0(推荐 LTS 版本 16.17.0) JavaScript 包管理器 NPM(版本请与 Node.js 版本匹配)
第一步:创建 uni-app 项目
在 HBuilderX IDE 环境中,创建 uni-app 项目。详细步骤请参考《uni-app 官网文档》通过 HBuilderX 可视化界面。
如果您已创建项目,请忽略本步骤。
第二步:下载 Demo 源码
运行以下命令将 NEUIKit GitHub 源码项目 nim-uikit-uniapp.git 下载到 uni-app 项目中:
Bash# 找一个目录,clone 组件项目
git clone https://github.com/netease-kit/nim-uikit-uniapp.git
# 在您的项目根目录下执行以下命令,拷贝组件
mkdir -p ./pages/NEUIKit
# macOS
mv ${组件项目路径}/NEUIKit/* ./pages/NEUIKit
# windows
move ${组件项目路径}/NEUIKit/* .\pages\NEUIKit
下载成功后,目录结构如下图所示:
第三步:添加依赖和图片引入
-
在项目的根目录下添加依赖和图片引入。
Bash
npm init -y npm i nim-web-sdk-ng@10.4.0 @xkit-yx/im-store-v2@0.2.3 @xkit-yx/utils@0.5.6 dayjs@1.11.7 mobx@6.6.1 pinyin@3.1.0 --save
-
在您的项目根目录下执行以下命令,将组件需要的图片复制到
static
目录下,若命令执行不成功,请按照路径手动复制。Bash
mkdir -p static
-
当前静态资源放置在网易对象存储(Netease Object Storage,NOS) 中,您可通过链接的方式在组件中进行访问。
由于访问频率有限制,建议您将静态资源放置在您的 业务服务器 上,然后修改
/pages/NEUIKit/components/Icon.vue
组件中的链接即可。Bash
# macOS cp -r pages/NEUIKit/static static/YX_IMG # windows xcopy /E pages\NEUIKit\static static\YX_IMG
第四步:引入并初始化组件
初始化 NEUIKit 组件
在 App.vue
文件引入 NEUIKit 组件, 参考以下代码初始化 nim
和 store
。
JSX<script lang="ts">
import RootStore from "@xkit-yx/im-store-v2";
import V2NIM, { V2NIMConst } from "nim-web-sdk-ng/dist/v2/NIM_UNIAPP_SDK";
import {
customRedirectTo,
customReLaunch,
customSwitchTab,
} from "./pages/NEUIKit/utils/customNavigate";
import { getMsgContentTipByType } from "./pages/NEUIKit/utils/msg";
import { STORAGE_KEY } from "./pages/NEUIKit/utils/constants";
import { isWxApp } from "./pages/NEUIKit/utils";
import {
V2NIMMessage,
V2NIMMessagePushConfig,
} from "nim-web-sdk-ng/dist/v2/NIM_UNIAPP_SDK/V2NIMMessageService";
// #ifdef APP-PLUS
export default {
onLaunch() {
const imOptions = {
appkey: "", // 请填写你的appkey
account: "", // 请填写你的account
token: "", // 请填写你的token
}
if (imOptions) {
this.initNim(imOptions);
} else {
// 需要登录, 跳转登录页
}
},
methods: {
initNim(opts) {
// 初始化nim sdk
const nim = (uni.$UIKitNIM = V2NIM.getInstance(
{
appkey: opts.appkey,
needReconnect: true,
// "reconnectionAttempts": 5,
debugLevel: "debug",
apiVersion: "v2",
},
{
V2NIMLoginServiceConfig: {
lbsUrls: isWxApp
? ["https://lbs.netease.im/lbs/wxwebconf.jsp"]
: ["https://lbs.netease.im/lbs/webconf.jsp"],
linkUrl: isWxApp ? "wlnimsc0.netease.im" : "weblink.netease.im",
/**
* 使用固定设备ID,
*/
isFixedDeviceId: true,
},
}
));
// 初始化store
const store = (uni.$UIKitStore = new RootStore(
nim,
{
addFriendNeedVerify: false,
teamAgreeMode:
V2NIMConst.V2NIMTeamAgreeMode.V2NIM_TEAM_AGREE_MODE_NO_AUTH,
sendMsgBefore: async (options: {
msg: V2NIMMessage;
conversationId: string;
serverExtension?: Record<string, unknown>;
}) => {
const pushContent = getMsgContentTipByType({
text: options.msg.text,
messageType: options.msg.messageType,
});
const yxAitMsg = options.serverExtension
? options.serverExtension.yxAitMsg
: { forcePushIDsList: "[]", needForcePush: false };
// 如果是 at 消息,需要走离线强推
const { forcePushIDsList, needForcePush } = yxAitMsg
? // @ts-ignore
store.msgStore._formatExtAitToPushInfo(
yxAitMsg,
options.msg.text
)
: { forcePushIDsList: "[]", needForcePush: false };
console.log("forcePushIDsList: ", forcePushIDsList);
const { conversationId } = options;
const conversationType =
nim.V2NIMConversationIdUtil.parseConversationType(conversationId);
const targetId =
nim.V2NIMConversationIdUtil.parseConversationTargetId(
conversationId
);
const pushPayload = JSON.stringify({
// oppo
oppoField: {
click_action_type: 4, // 参考 oppo 官网
click_action_activity: "", // 各端不一样 TODO
action_parameters: {
sessionId: targetId,
sessionType: conversationType,
}, // 自定义
},
// vivo
vivoField: {
pushMode: 0, //推送模式 0:正式推送;1:测试推送,不填默认为0
},
// huawei
hwField: {
click_action: {
type: 1,
action: "", // 各端不一样 TODO
},
androidConfig: {
category: "IM",
data: JSON.stringify({
sessionId: targetId,
sessionType: conversationType,
}),
},
},
// 通用
sessionId: targetId,
sessionType: conversationType,
});
const pushConfig: V2NIMMessagePushConfig = {
pushEnabled: true,
pushNickEnabled: true,
forcePush: needForcePush,
forcePushContent: pushContent,
forcePushAccountIds: forcePushIDsList,
pushPayload: "{}",
pushContent,
};
return { ...options, pushConfig };
},
},
"UniApp"
));
nim.V2NIMLoginService.login(opts.account, opts.token).then(() => {
customSwitchTab({
url: "/pages/Conversation/index",
});
});
},
logout() {
},
},
};
</script>
<style>
uni-page-body {
height: 100%;
}
uni-page-body > uni-view {
height: 100%;
}
</style>
初始化 NimKitCore
在初始化 NimKitCore
时,您需要根据是否是微信小程序,传入不同的 lbsUrls
和 linkUrl
。
JavaScriptconst nim = (uni.$UIKitNIM = new NimKitCore({
initOptions: {
appkey: "", // 请填写您的 appkey
account: "", // 请填写您的 account
token: "", // 请填写您的 token
lbsUrls: isWeixinApp
? ["https://lbs.netease.im/lbs/wxwebconf.jsp"]
: ["https://lbs.netease.im/lbs/webconf.jsp"],
linkUrl: isWeixinApp ? "wlnimsc0.netease.im" : "weblink.netease.im",
needReconnect: true,
/**
* 使用固定设备 ID,
*/
isFixedDeviceId: true,
// "reconnectionAttempts": 5,
debugLevel: "debug",
},
platform: "UniApp",
}));
第五步:配置路由
-
在
pages/NEUIKit/utils/customNavigate.ts
中,修改preUrl
:JavaScript
const preUrl = '/pages/NEUIKit'
-
在您项目的
pages.json
文件中的更新pages
路由:JSON
{ "pages": [ { "path": "pages/NEUIKit/pages/Conversation/index", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Login/index", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Chat/message/p2p-set", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Group/group-set/index", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Group/group-set/group-info-edit", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Contact/index", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Contact/contact-list/group-list", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Contact/contact-list/valid-list", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Contact/contact-list/black-list", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Chat/index", "style": { "navigationBarBackgroundColor": "#F6F8FA", "navigationBarTextStyle": "black", "navigationStyle": "custom", "enablePullDownRefresh": false, "app-plus": { "softinputNavBar": "none", "bounce": "none" } } }, { "path": "pages/NEUIKit/pages/Chat/video-play", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Group/group-member/index", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Group/group-create/index", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Group/group-add/index", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Friend/add-friend/index", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/user-card/friend/index", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/user-card/my/index", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/user-card/my/setting", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/user-card/my-detail/index", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/user-card/detail-item/index", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Group/group-set/nick-in-team", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Group/group-set/group-manage", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Group/group-set/transform-team", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Group/group-set/group-manager-list", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Group/group-set/add-group-manager", "style": { "navigationStyle": "custom" } }, { "path": "pages/NEUIKit/pages/Chat/forward", "style": { "navigationStyle": "custom" } } ], "globalStyle": { "navigationBarTextStyle": "black" }, "tabBar": { "backgroundColor": "#F6F8FA", "color": "#999999", "selectedColor": "#337EFF", "height": "60px", "list": [ { "text": "消息", "iconPath": "static/YX_IMG/conversation.png", "selectedIconPath": "static/YX_IMG/conversation-selected.png", "pagePath": "pages/NEUIKit/pages/Conversation/index" }, { "text": "通讯录", "iconPath": "static/YX_IMG/contact.png", "selectedIconPath": "static/YX_IMG/contact-selected.png", "pagePath": "pages/NEUIKit/pages/Contact/index" }, { "text": "我的", "pagePath": "pages/NEUIKit/pages/user-card/my/index", "iconPath": "static/YX_IMG/me.png", "selectedIconPath": "static/YX_IMG/me-selected.png" } ] } }
第六步:运行 Demo
在 uni-app IDE 中,运行 Demo:
自定义开发
API 参考
IM uni-app Demo 基于 UIKitStore
开发,相关 API 详情请参考 UIKitStore。
例如,您想获取 IM uni-app UIKit 的会话未读数,示例代码如下:
JavaScriptconst unRead = store.uiStore.sessionUnread
使用原生 SDK 中的方法
如果您需要自行实现目前 uni-app UIKit 还未实现,但原生的 IM uni-app SDK 已提供的能力。您可以通过调用原生 IM uni-app SDK 中提供的接口来实现。原生 uni-app SDK 中的 API,请参考 NIM Web SDK。
例如,您想对 IM uni-app UIKit 的消息历史进行全文检索(按时间分页搜索),可以调用原生 SDK 中的 msgFtsInServerByTiming
方法,示例代码如下:
JavaScriptuni.$UIKitNIM.nim.msgFtsInServerByTiming({
keyword: '您好',
})
以上示例中的 uni.$UIKitNIM.nim
为原生 NIM uni-app SDK 的实例。