小程式項目新增一聊天室功能;
控件是用該部落客的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>