首页 技术JS正文

vue搭建基于融云的聊天室

薄洪涛 JS 2020-03-31 321 1 vue聊天室

    最近项目比较忙,在做完了一个在线问诊的项目后,想给大家分享下其中用到的,但是百度上资料又比较少的技术

    需求背景:医生需要和患者在线沟通,我们已经做完了基于融云的app原生聊天室开发,但是需要在开发出一套web版的聊天室,这样可以嵌入到其他公司的app里面

    技术方案:我们选用了vue作为前端开发框架,使用localstorage作为聊天记录的缓存,实现了医生和患者聊天的需求

搭建:

  1. index.html引入融云资源

<script src="https://cdn.ronghub.com/RongIMLib-2.5.0.min.js"></script>
<script src="https://cdn.ronghub.com/Libamr-2.2.5.min.js"></script>
<script src="https://cdn.ronghub.com/RongIMVoice-2.2.6.js"></script>
<script src="http://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>

  2. 初始化融云(token要写接口去获取),需要注意的是,要想聊天,两个端appid必须一致

//初始化融云
initRongCloud() {
    var appkey = this.appkey
    var token = this.token
    console.log("开始初始化")
    const _this = this
    if (!appkey || !token) {
        alert('appkey 和 token 不能为空')
    } else {
        init({
            appkey: appkey,
            token: token
        }, this.addPromptInfo)
    }
}

3.使用融云的方法来监听收到的消息,举个例子,这一块融云的文档写的很详细

// 文本消息
SET_ANSWER_TXT (state, playload) {
  let say = {
    type: 'txt',
    css: 'left',
    txt: playload.content.content,
    headImg: playload.content.user.portrait,
    msgId: playload.messageId,
    targetId: playload.targetId,
    Name: playload.content.user.name,
    sendTime: playload.sentTime
  }
  if (state.targetId === playload.targetId) {
    state.answer.push(say)
    // 保存历史聊天记录
    let tmp = JSON.stringify(state.answer)
    localStorage.setItem(state.targetId, tmp)
  }
},

4. 使用vue的watch和computed来检测数据的变动,使用store来存储每次发送的消息,聊天界面的聊天信息展示是遍历的store中的数据

computed的定义

当其依赖的属性的值发生变化时,计算属性会重新计算,反之,则使用缓存中的属性值。

watch的定义

如果watch监测的是一个对象的话,直接使用watch是不行的,此时我们可以借助于computed计算属性来完成

mounted() {
    //融云初始化(获取token,初始化融云实例)
     this.start()
    this.$refs.content.scrollTop = this.$refs.content.scrollHeight;

},
watch: {
    answer() {
        this.$nextTick(() => {
            const list = document.getElementById('test')
            //医生回复消息集合
            var answer_doctor = this.$store.state.answer
            console.log(answer_doctor)
            if(answer_doctor!==null) {
                let len = answer_doctor.length - 1
                //医生发送咨询结束消息
                if (answer_doctor[len].txt !== undefined && answer_doctor[len].txt === '在线咨询已结束') {
                    console.log('在线咨询已结束')
                    document.getElementById('send').style.display = 'none'
                    document.getElementById('topTime').style.display = 'none'
                    document.getElementById('rebuy').style.display = 'flex'
                }else if(answer_doctor[len].txt !== undefined && answer_doctor[len].txt === '医生已退回咨询,问诊费用将原路返回') {
                    console.log('医生已退回咨询')
                    document.getElementById('send').style.display = 'none'
                    document.getElementById('topTime').style.display = 'none'
                }else if(answer_doctor[len].txt !== undefined && answer_doctor[len].txt.startsWith('您的在线咨询结束时间已延长')) {
                    document.getElementById('rebuy').style.display = 'none'
                    document.getElementById('send').style.display = 'flex'
                    document.getElementById('topTime').style.display = 'flex'
                }
            }
            document.documentElement.scrollTop = list.scrollHeight
            //如不行,请尝试-> list.scrollTop = list.scrollHeight
        })
    }
},

聊天页面的展示(分左右两块,左面是接受的消息,右边是发送的消息,这是代码是发送的消息)

<div v-if="(data.targetId === this.$store.state.targetId) && (data.css === 'right')" class="right" :id="data.msgId">
  <van-image class="item-media" round fit="cover" :src="data.headImg" />
  <div class="item-inner">
    <!-- 文本消息 -->
    <!-- <span class="showtime">{{func(data.sendTime)}}</span> -->
    <div class="item-subtitle">{{data.Name}}</div>
    <div class="item-title-row" v-if="data.type == 'txt'">
      <div class="item-title txt">{{data.txt}}</div>
    </div>
    <!-- 图片消息 -->
    <div class="item-title-row showImg" v-if="data.type == 'image'">
      <van-image :src="data.txt" fit="fill" @click="imgShow(data.msgId,1)"/>
    </div>
  </div>
</div>


4.使用store.js 来存储消息,当收到消息的时候,将信息存到内存中即store.js定义的数组中(store中定义的对象如果页面不刷新就不会丢失),每次当收到消息或者发送消息的时候,存到localstorge里面,可以看上面那段代码

参考源码:https://github.com/BoHongtao/vue-rongcloud

参考教程: https://juejin.im/post/5d38677af265da1b88121f72



版权声明

本文仅代表作者观点,不代表本站立场。
本文系作者授权发表,未经许可,不得转载。

评论

精彩评论
  • 2020-04-20 08:21:34

    我也用过vue,写的不错。