这段时间一直在利用uniapp做聊天室的功能,这里分享下发送新消息,接收新消息怎么像QQ那样滚动加载。
首先我是查了一下网上的朋友,看了下大多都是使用scroll-top实现的,所以我也试了一下这个东西,确实可以实现,但是他获取dom的速度着实让人着急,而且不大适用加载历史记录,因为太慢了,我不知道网友是不是有更好的方式加载聊天记录,我这边不管怎么加载都会延迟一会,所以会跳动一下,看着让人着实难受,所以我是写了一个opacity延迟一会再显示,让人看起来舒服一点,
好了,上边纯属瞎扯,进入正题,我这里使用也是scroll-view这个组件,不过我是用是scroll-into-view锚点的方式加载历史数据,分页,发送消息以及新消息,历史数据和分页我是直接加载的没有使用动画滚动,发送和新消息使用了滚动,动画是否使用用的是 :scroll-with-animation="animation"这个鬼东西控制的,上代码。
<scroll-view id="scrollview" @scroll="chatScroll" class="chat-window" :scroll-y="true" :style="{'max-height': style.contentViewHeight + 'px'}"
:scroll-with-animation="animation" @scrolltoupper="scrolltouppe" :scroll-into-view="toView" >
然后在你聊天记录里搞个id,animation是在data里定义的布尔值,这里我举个例子,代码太多就不复制
<view v-for="(item,index) in ForchatData" >
这里是你的消息内容,图片,语音,文字等等吧。
<view style="height: 40upx;clear: both;" :id="'toView'+index"></view>
ID就是写在上边就可以,当然你也可以写在循环上边的标签,不过我试了一下,因为锚点大家都知道是跳到标签的上边框,所以如果写在上边就会出现底下部分被遮盖,所以写在最后比较好点
</view>
然后现在就可以使用了,注意这里因为历史记录加载过慢,所以刚加载的时候你需要写在nextTick里面,如下
that.$nextTick(function() {
setTimeout(() => {
that.contentViewMain();
}, 20)
})
这里以防万一我又加了一个延迟,不影响。 看下contentViewMain里面写的什么,如下:
contentViewMain() {
let that = this;
that.toView = ""
that.$nextTick(function() {
that.toView = "toView" + (that.ForchatData.length - 1)
})
},
首先我这里先写了一个that.toView =
“”,因为你直接改that.toView他默认不变,所以先置空再赋值就有作用了,that.ForchatData这个东西就是你的消息数据,因为上边咱们提到只在有新消息和发送才会启动动画,所以加载历史消息之前咱的that.animation
= false;,然后在发文字,发图片,发语音这些之前再that.animation = true;并且调用下咱的锚点函数this.contentViewMain()就可以实现滚动发送新消息了。
这样会比scroll-top省很多代码。兼容性的话,安卓我是真机测试没啥问题,ios还没测。我看uniapp对于scroll-into-view并没有写兼容问题,另外说下一个小问题,就是上边不管用scroll-top还是scroll-into-view,真机上上拉分页的时候都会先跳到顶部再回来,这点很让人头疼,等解决这个问题再补上。