当 Vue H5 项目需要接入 Udesk WebIM 网页插件 您所在的位置:网站首页 udesk总部 当 Vue H5 项目需要接入 Udesk WebIM 网页插件

当 Vue H5 项目需要接入 Udesk WebIM 网页插件

2023-03-19 23:36| 来源: 网络整理| 查看: 265

〇、前言

公司 H5 项目需要接入 IM ,其他平台目前已经对接了 Udesk 提供的 IM 服务,H5 也需要保持一致,开发之前早就听安卓和 iOS 同事说 Udesk 的坑很多,源码他们都改了好几版,不知道 H5 的会不会也这样刺激,抱着忐忑的心情准备试一试。

本文记录了一次 Vue 版本 H5 接入 Udesk WebIM 网页插件的踩坑过程,一方面是自己记录一下,另外一方面是希望能帮助到即将踩坑的童鞋,避免踩坑。

一、注册 Udesk

如果没有账号需要进行注册。

Udesk官网:www.udesk.cn

注册之后可以免费向客服获取到试用的账号,自己或者公司的账号要使用 IM 插件的功能需要付费开通权限。

二、使用 IM 插件

这里列举使用的主要几个过程 具体详细过程可参考udesk文本IM对接文档:www.udesk.cn/doc/thirdpa…

1.执行 Udesk 提供的函数

Udesk 提供了一个创建 script 加载远端资源的函数:

(function (a, h, c, b, f, g) { a.UdeskApiObject = f a[f] = a[f] || function () { (a[f].d = a[f].d || []).push(arguments) } g = h.createElement(c) g.async = 1 g.src = b c = h.getElementsByTagName(c)[0] c.parentNode.insertBefore(g, c) })( window, document, 'script', 'https://assets-cli.udesk.cn/im_client/js/udeskApi.js', 'ud' ) 复制代码

接入过百度统计的童鞋肯定会觉得似曾相识。 其作用是创建一个用于加载 Udesk WebIM 网页插件 的 script 标签,插入到 head 中, 由于给 script 标签添加了 async 属性,当 js 资源加载完成后会立即执行。 执行后会在window上挂载一个 ud 对象,初始化的时候需要向 ud 传入参数。

2.初始化 ud ud({ "code": "xxxx", "link": "https://xxx.xxxx.cn/im_client/?web_plugin_id=1", "isInvite": true, "mode": "inner", "color": "#307AE8", "pos_flag": "srb", "language": "en-us", "onlineText": "联系客服,在线咨询", "offlineText": "客服下班,请留言", "mobile": { //为响应式布局,提供pc、mobile自定制 "mode": "blank", "color": "#307AE8", "pos_flag": "crb", "onlineText": "联系客服,在线咨询", "offlineText": "客服下班,请留言" } }) 复制代码

初始化可传的常用参数是这些,除了 code 和 link 必传,其他的可以根据需求选填。

在 vue 中我们可以编写一个 udsk 工具函数

// udesk.js export default { init () { if (!window.ud) { this.createUdeskScript() } }, createUdeskScript () { (function (a, h, c, b, f, g) { a.UdeskApiObject = f a[f] = a[f] || function () { (a[f].d = a[f].d || []).push(arguments) } g = h.createElement(c) g.async = 1 g.src = b g.id = useUdeskScriptId c = h.getElementsByTagName(c)[0] c.parentNode.insertBefore(g, c) })( window, document, 'script', 'https://assets-cli.udesk.cn/im_client/js/udeskApi.js', 'ud' ) const ud = window.ud const udParams = { code, link, ... // 其他参数 } } ud(udParams) } } 复制代码

在 main.js 中引入使用即可

// main.js import Udesk from './utils/udesk' Udesk.init() 复制代码 3.Udesk 全局对象

初始化完成后会把udesk的挂载在window上,打印出来是这样子的:

检查dom节点,会发现 udesk 创建了 id 为 udesk_container 的 div ,结构如下。

id 为udesk_btn 和 udesk_panel 的 div 容器分别是打开IM会话面板的按钮(可自定义位置和图片样式等)和 IM 会话面板。

IM 的会话面板通过 iframe 嵌入的方式进行显示。会话面板如下图:

到这里,最基础的 IM 功能基本上可用了。但是,如果要补充细节的话,我们还需要做的可(zhen)能(de)还有很多。

三、Udsk 信息按钮的自定义 为什么要自定义? 1.这次项目中,需求是需要信息按钮下方会有另外一颗按钮悬浮在右下角,样式风格统一,如下:

Udesk 官方后台提供了 IM 信息按钮定位的配置,可以自己在后台调节位置,但坑爹的是不可以调节未读红点的样式,而且定位会导致和另外一个 icon 的对齐有误差。

2.未读显示不同页面样式不一样,比如这样:

3.Udesk 初始化后同一个页面的样式是固定的,单页面应用(Vue,React)要不同页面不同样式,所以用 Udesk 配置自动生产的信息按钮不满足我们的需求。

综上三点决自己写未读信息的按钮样式,根据提供的接口回调处理未读数。

四、同步未读信息数

由于多个页面都放了信息未读数的入口,因此我们需要在收到信息的时候同步到每个页面,未读数目用 Vuex 管理是不错的选择。

ud 的初始化中给到了一个 onUnread 回调函数,我们可以在里面处理未读数目。考虑到 H5 项目用户很大几率收到未读消息后切出去,因此很有必要缓存未读数。

onUnread: function (data) { const count = data.count Store.commit('SET_UNREADCOUNT', count) _this.setLocal(count) //最后缓存到本地 下次打开保留上次的未读数目 } 复制代码

同时,在初始化之后要从缓存中拉取未读数

//udParams 中的 onReady onReady: function() { // 从缓存中获取未读数目 const onUnreadCount = _this.getLocal() if (onUnreadCount && onUnreadCount * 1 > 0) { Store.commit('SET_UNREADCOUNT', onUnreadCount) } }, getLocal () { return localStorage.getItem('onUnread') } 复制代码

这样子,在需要用到未读数的组件或者页面中就可以从 store 中直接取出来用,简单省心。

五、遇到的坑 1.Vue 项目中打开会话面板点击浏览器回退按钮,我们期待的正常情况是关闭会话面板,回到之前的页面,但是 Vue 中不是这样子,是页面路由回退,会话面板还在。

分析原因:导致此问题的原因是因为 Vue 是单页面应用,浏览器的回退前进是控制 Vue 的路由,整个页面没有去新,而且会话面板打开状态点击回退不会触发关闭会话面板关闭,需要手动点击最小化,会话面板才会消失。

怎么解决呢? 查了下文档,Udesk 提供了两个方法:hidePanel 和 showPanel,分别是隐藏会话面板和打开会话面板。

文档推荐的使用方法:ud("hidePanel"),ud("showPanel"),除了文档推荐的这种方法,还可以用 ud.showPanel() 和 ud.hidePanel()。 配合这两个方法,我们就可以解决上面的问题了。

开“淦”!!

新增一个页面用于储存路由,假设这个页面叫做 UdeskPanel。

这个页面不写任何样式,它的作用只是用来处理 Udsk 的会话面板逻辑的。路由命中这个页面就调用 showPanel 方法,页面离开就调用 hidePanel 方法,这样子上面的就解决了。

为了统一管理 Udesk 的方法,我们把显示隐藏会话面板的方法集成在 udesk.js 中:

// udesk.js export default { init () { if (!window.ud) { this.createUdeskScript() } }, openUdPanel () { if (window.ud) { this.show() const ud = window.ud ud('showPanel') } }, hideUdPanel () { if (window.ud) { const ud = window.ud ud('hidePanel') } }, createUdeskScript () { (function (a, h, c, b, f, g) { a.UdeskApiObject = f a[f] = a[f] || function () { (a[f].d = a[f].d || []).push(arguments) } g = h.createElement(c) g.async = 1 g.src = b g.id = useUdeskScriptId c = h.getElementsByTagName(c)[0] c.parentNode.insertBefore(g, c) })( window, document, 'script', 'https://assets-cli.udesk.cn/im_client/js/udeskApi.js', 'ud' ) const ud = window.ud const udParams = { code, link, ... // 其他参数 } } ud(udParams) } } 复制代码

UdeskPanel 页面的代码:

// UdeskPanel.vue import Udesk from '../utils/udesk' export default { name: 'UdeskPanel', data () { return {} }, mounted () { Udesk.openUdPanel() }, beforeRouteLeave (to, from, next) { Udesk.hideUdPanel() next() }, methods: {} } 复制代码

上面的问题解决了,新的问题来了,用户点击 Udesk 会话面板的最小化关闭了会话面板,我们停留在了 UdeskPanel 的空白页面。

这不是我们想要的。

所以我们还应该捕获关闭会话面板的事件,查了文档,ud 提供了一个 onToggle 的回调方法。检测当前会话面板是否打开,visible 为 true 时则是打开状态。

onToggle: function(data) { if (!data.visible) { // 对话窗口关闭 } else { // 对话窗口打开 } } 复制代码

利用这个方法,我们可以配合 Vuex 全局维护一个会话面板是否打开的变量,UdeskPanel 页面中监听这个变量,当为 false 的时候去操作路由回退,前面的代码就变成下面的样子:

// UdeskPanel.vue import Udesk from '../utils/udesk' import { mapGetters } from 'vuex' export default { name: 'UdeskPanel', data () { return {} }, mounted () { Udesk.openUdPanel() }, computed: { ...mapGetters(['udTraceIsUP']), showPanel () { return this.$store.state.udesk.showPanel } }, watch: { showPanel (newVal, oldVal) { if (newVal === false) { this.$router.go(-1) } } }, beforeRouteLeave (to, from, next) { Udesk.hideUdPanel() next() }, methods: {} } 复制代码

似乎已经解决问题了。

但是,如果用户直接打开的页面是会话面板的这个页面,点击最小化,页面还是会在当前。

原因是当页面没有上一个路由记录时候, this.$router.go(-1) 就不会达到我们的要求了,因此需要其他操作离开当前页面,最好的方式是返回到首页。再优化一下代码:

showPanel(newVal, oldVal) { if (newVal === false) { if (window.history.length


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有