飙血推荐
  • HTML教程
  • MySQL教程
  • JavaScript基础教程
  • php入门教程
  • JavaScript正则表达式运用
  • Excel函数教程
  • UEditor使用文档
  • AngularJS教程
  • ThinkPHP5.0教程

六、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-聊天界面容器的实现

时间:2021-12-27  作者:zhimitec  
六、Uniapp+vue+腾讯IM+腾讯音视频开发仿微信的IM聊天APP,支持各类消息收发,音视频通话,附vue实现源码(已开源)-聊天界面容器的实现 基于uni-app技术开发的仿微信界面IM实例项目,开源Vue版本源码,对于要求高的开发者我们也开发了NVUE版本,实现了文本消息、图文消息、表情(gif动画),图片预览,图片编辑,视频预览,视频编辑,仿微信的图片选择、编辑、长按菜单等功能

会话好友列表的实现

1、项目引言
2、腾讯云后台配置TXIM
3、配置项目并实现IM登录
4、会话好友列表的实现
5、聊天输入框的实现
6、聊天界面容器的实现
7、聊天消息项的实现
8、聊天输入框扩展面板的实现
9、聊天会话管理的实现
10、聊天记录的加载与消息收发
11、定位SD配置与收发定位消息
12、贴图表情的定制化开发
13、腾讯云后台配置TRTC功能
14、集成音视频通话功能
15、集成仿微信的拍照,相册选择插件
16、集成美颜功能
17、集成TPNS消息推送(暂未接入)


@

目录
  • 会话好友列表的实现
  • 文章概述
  • 聊天界面容器的实现
    • 1.为什么要实现一个聊天界面容器
    • 2. 聊天界面容器的设计
      • 2.1 滚动到底部
      • 2.2输入法高度自适应
      • 2.3滚动加载
  • 项目开源地址及交流群


文章概述

上一次我们讨论过聊天输入框的实现,实现文本,语音,标签的编辑发送,而本次我们的关注点将回归到整个聊天界面容器的实现。


聊天界面容器的实现

1.为什么要实现一个聊天界面容器

一般情况下,开发者会采用直接在对应的界面中实现聊天界面UI的方式做开发。这种开发思路无可厚非,但是如果我们要实现跨平台的聊天IM,那么我们不免要遇到组件之间的事件冲突,多平台表现差距的问题,特别是在聊天中我们还需要实现滚动加载。如果说我们在每个界面都实现了一套代码,那么会导致整体代码的可维护性下降,因此我们有必要实现一个聊天界面容器,将消息显示,滚动加载,长按菜单,输入,编辑等都在这里面做好兼容处理,使得界面和业务组件实现解耦合。
在这里插入图片描述

2. 聊天界面容器的设计

聊天界面容器的设计很简单,我们大概整理一下需要实现以下几点功能。

  • 滚动到底部
  • 输入法高度自适应
  • 滚动加载

2.1 滚动到底部

首先我们需要明确我们的聊天界面肯定是需要滚动的,并且在接收/发送消息的时候我们需要滚动在最底部,类似微信收发消息的效果,组件我们肯定只有scrollView可以使用,具体实现如下

<scroll-view
      ref="scroll"
      class="chat-layout__scroll"
      :style="{
        height: scrollBoxHeight
      }"
      :scroll-y="!inUpperLoading"
      :upper-threshold="0"
      :show-scrollbar="false"
      :scroll-top="scrollTop"
      @scrolltoupper="onScrollToUpper"
      @click="onScrollClick"
      @scroll="onScroll"
    >
      <text
        v-if="inUpperLoading && !end"
        class="chat-layout__scroll-loading"
      >
      </text>
      <slot></slot>
      <view ref="ending"></view>
    </scroll-view>

实现滚动到底部,一般而言是只能使用scrollTop,而这样为了兼容nvue,我们采用weex原生的dom模块获取可滚动高度 - 容器高度就可以实现可滚动高度。

      async scrollToBottom (retouchCount) {
        if (域名perLoading || 域名llBottoming) {
          return
        }
        域名llBottoming = true
        // await this.$nextTick()
        // this.$域名y(100)
        // let view = await this.$域名y(this, \'.chat-layout__scroll\')
        // 域名llTop = 域名llHeight

        // nvue必须使用下面这种
        await this.$nextTick()
        域名llToElement(this.$域名ng, { animated: false })
        域名llBottoming = false
        await this.$nextTick()
        retouchCount = retouchCount || 0
        retouchCount++
        // 最多5次重新滚动到底部的测试, nvue下面的渲染并且是nextTick之后就百分百正常
        域名omponentRect(this.$域名ll, ({ size }) => {
          let { detail } = 域名llEvent
          if (!detail) {
            域名llTop = 0
            if (retouchCount < 5) {
              域名llToBottom(retouchCount)
            }
          } else {
            域名llTop = 域名llHeight - 域名ht
            // 域名(\'重新定位scrollTop\')
            if (retouchCount < 5) {
              域名llToBottom(retouchCount)
            }
          }
        })
      }

2.2输入法高度自适应

一般情况下在vue界面,我们input focus之后是会自动适应输入法高度,然而在nvue中,当我们界面中嵌套了视频播放器之类的,会导致input高度计算错误,因此我们需要手动监听输入法高度变化,然后做一个适应性的收缩界面容器即可。

<view
    class="chat-layout"
    :style="{
      paddingBottom: paddingBottomHeight
    }"
  >
  </view>
域名yboardHeightChange(域名yboardHeightChange)

// methods中
async onKeyboardHeightChange ({ height }) {
  域名ingBottomHeight = height
  await this.$nextTick()
  height && 域名llToBottom()
},

2.3滚动加载

滚动加载有很多方式实现,这里我们只简易的实现了一个,监听scrollView的scrolltoupper事件确定是否加载,然后我们抛出给业务层控制滚动加载。

    <scroll-view
      ref="scroll"
      class="chat-layout__scroll"
      :style="{
        height: scrollBoxHeight
      }"
      :scroll-y="!inUpperLoading"
      :upper-threshold="0"
      :show-scrollbar="false"
      :scroll-top="scrollTop"
      @scrolltoupper="onScrollToUpper"
      @click="onScrollClick"
      @scroll="onScroll"
    >
onScrollToUpper: throttle(async function() {
        if (域名perLoading || 域名bleUpperLoading || 域名) {
          return
        }
        域名perLoading = true
        let oldChildrens = this.$域名域名th
        this.$emit(\'upperLoading\', async isEnd => {
          if (isEnd) {
            域名bleUpperLoading = true
          }
          await this.$nextTick()
          let newChildrens = this.$域名域名th
          域名perLoading = false
          let refEl = this.$域名dren[newChildrens - oldChildrens]
          域名llToElement(refEl, { animated: false })
        })
      }, 200, {
        leading: true,
        trailing: false
      }),

而对于业务层来说,接收到upperLoading事件之后做数据加载,然后反馈加载完成即可

async loadMoreLog (next) {
  域名(\'loadMoreLog\')
  await 域名ogs(域名enLogLen)
  await this.$nextTick()
  next(false)
},

项目开源地址及交流群

项目开源地址:https://域名/ckong/域名域名
Uniapp开发交流群:755910061

标签:编程
湘ICP备14001474号-3  投诉建议:234161800@qq.com   部分内容来源于网络,如有侵权,请联系删除。