小程序项目新增一聊天室功能;

控件是用该博主的https://blog.csdn.net/sinat_27612147/article/details/78456363;感谢博主提供如此方便的源码;

功能需求:

一:WebScoket链接

这个是要创建小程序与后台间的连接,比较简单,微信api都有提供;

https://developers.weixin.qq.com/miniprogram/dev/api/network-socket.html#wxclosesocket

二、聊天室置底

本人使用该控件时发现并没有很好的解决聊天置底问题,跟进自己想法改造下;

1、组件<scroll-view> 设置scroll-top属性  

这是我一开始的处理方式,在收到消息和发送消息时获取聊天记录列表,然后根据长度动态设置 scroll-top值

let chatItems = this.data.chatItems;
this.setData({
    scrollTopVal:chatItems.length*60+60  
})  //scrollTopVal是<scroll-view/>的scroll-top属性值,*60是我这一个聊天记录大概60

如果全是文字聊天这样是可行的,但是一旦出现了图片就不可行了。因为图片聊天高度是超过60的,我也不可能每次都去for聊天记录有多少图片,多少文字。

 

2、组件<scroll-view scroll-into-view="{{toView}}"> 设置scroll-into-view属性(值应为某子元素id(id不能以数字开头)。设置哪个方向可滚动,则在哪个方向滚动到该元素)

根据这个属性,我再列表的下方再添加一个<view id="toView"></view>的空标签;然后同理在发送和接受到消息的时候

this.setData({
    toView:'toView'
})

这样我们就可以保证scroll-view可以置底了,美滋滋;

三、聊天记录历史

描述:我们在小程序上是不可能保存所有的聊天记录,所以暂时是只保存了50条记录,超过50条咋办?肯定是通过接口请求后台再渲染到小程序上。原以为很简单,只要根据<scroll-view/>提供的 bindscrolltoupper 属性便可实现,即滚动到顶部时触发scrolltoupper 事件请求接口获取数据,再将新老数据concat拼接。

问题来了:这样一来,我们就永远是在顶部了,看过往数据只能上拉,看完再下拉到顶部加载新的记录;我们要实现的是像微信那样看记录只要一直下拉。

解决方案:依旧是用scroll-into-view属性,我们拿到聊天记录数据时就给第一天添加一个id,然后出发scrolltoupper事件时获取该id,然后数据拼接完成后通过scroll-into-view回到id位置;(该方案并不优雅,还望各位大神提供更好的解决方案,谢谢

.js
console.log('更多历史记录');
let store = [{type:'text',content:'测试1'},{type:'text',content:'测试2'},{type:'text',content:'测试3'},{type:'text',content:'测试4'},{type:'text',content:'测试5'},{type:'text',content:'测试6'},{type:'text',content:'测试7'},{type:'text',content:'测试8'},{type:'text',content:'测试9'},{type:'text',content:'测试10'},{type:'text',content:'测试11'},{type:'text',content:'测试12'},{type:'text',content:'测试13'}];//测试数据
      let currChatItems = this.data.chatItems;
      store[0].showId = new Date().getTime();//给第一条数据添加id(注:scroll-into-view的值应为某子元素id(id不能以数字开头))
      let id='';
    //列表每个有id我都添加了.prevId这个类,是为了方便我下边找
      wx.createSelectorQuery().selectAll('.prevId').fields({ 
        id:true,
      }, function(res){
        id = res[0].id;
        console.log(res)
      }).exec();
      this.setData({
        chatItems:store.concat(currChatItems),
      },()=>{
        this.setData({ 
          toView:id,
          loading:true
        })
      })
    }

.wxml
<template name="chat-item">
    <view id="{{item.showId?'view'+item.showId:''}}" class="{{item.showId?'prevId':''}}">
        <block wx:if="{{item.type!=='custom'}}">
            <template is="chat-time" data="{{showTime:item.showTime,time:item.time}}"/>
            <template is="chat-word"
                      data="{{length:length,index:index,headUrl:item.headUrl,isMy:item.isMy,showTime:item.showTime,time:item.time,content:item.content,type:item.type,sendStatus:item.sendStatus}}"/>
        </block>
        <block wx:else>
            <template is="chat-custom" data="{{content:item.content}}"/>
        </block>
    </view>
</template>

 

Logo

致力于链接即构和开发者,提供实时互动和元宇宙领域的前沿洞察、技术分享和丰富的开发者活动,共建实时互动世界。

更多推荐