聊天對話框項目的幾點(diǎn)思考
共 2328字,需瀏覽 5分鐘
·
2024-06-06 21:48
近一周,原來同事拉著幫忙做了一個聊天的小項目,主要是和后端這邊對接聊天室的接口和前端交互。
收發(fā)消息通過webSocket瀏覽器原生接口就行,API很簡單。保持ws連接活躍,需要實(shí)現(xiàn)心跳消息重連等操作。
功能界面大概就是這樣,能夠發(fā)送文字、圖片、表情,和自定義的名片信息。
1、用戶聊天信息如何分列呈現(xiàn)?
首先實(shí)現(xiàn)是同一用戶的消息保持在同一列,用戶變了后,消息在另一側(cè)展示,如此反復(fù)。于是大概是這樣的。
第一頁時,第一條或當(dāng)前消息的發(fā)送者和上一條消息的發(fā)送者相同時,保持在同側(cè),否則切換。
往前翻閱消息時,分頁數(shù)據(jù)由后往前推,即由分頁最后一條消息與消息列表已有的最前一條消息比較是否由同人發(fā)送。
calcPosChatMsgs() {let previousId = null, //初始化上一個ID變量prevActive = true,isNeedCalcNums = this.isNeedCalcNums,newMsgs = [],isSiblingActive;//重置為初始狀態(tài)this.isNeedCalcNums = 0;if(isNeedCalcNums) {newMsgs = this.chatMessageList.slice(0, isNeedCalcNums).reverse();//往前下頁的數(shù)據(jù)以它后面第一條數(shù)據(jù)的狀態(tài)為基準(zhǔn)isSiblingActive = this.chatMessageList[isNeedCalcNums].isActive;previousId = this.chatMessageList[isNeedCalcNums].user_info.user_id;newMsgs = newMsgs.map(function (item, index) {if(item.user_info.user_id == previousId) {item.isActive = isSiblingActive;}else {item.isActive = !isSiblingActive;isSiblingActive = !isSiblingActive;}previousId = item.user_info.user_id;return item;}).reverse();return newMsgs.concat(...this.chatMessageList.slice(isNeedCalcNums));}return this.chatMessageList.map(function (item, index) {if(index === 0 || item.user_info.user_id == previousId) {if(item.isActive === undefined) {item.isActive = prevActive;}else {prevActive = item.isActive;}}else {if(item.isActive === undefined) {item.isActive = !prevActive;prevActive = !prevActive;}else {prevActive = item.isActive;}}previousId = item.user_info.user_id;return item;});}
后面需求方查看后,感覺不對,“提出用戶自身的消息保持在右側(cè),其他人的消息左側(cè)顯示”,應(yīng)該和微信類似。大道至簡,一語點(diǎn)破的感覺,固定位置還有了某種意義上的歸屬和確定感。
2、消息隨著對話次數(shù)的增加,加載歷史分頁數(shù)據(jù)會不會導(dǎo)致重復(fù)消息的渲染呢?
如果是基于消息實(shí)時數(shù)量分頁的話,簡單分頁可能就會出問題了?;诖?,前端在將數(shù)據(jù)添加至消息列表中時,可先做一個去重操作;同時并不信任第一頁數(shù)據(jù)中返回的總頁數(shù),并以此作為是否允許加載下一頁的依據(jù)。
PS:這里等消息在頁面上渲染完成后,手動將滾動條往下移了部分位置,往上自動加載下一頁時,繼續(xù)等待用戶的行為來觸發(fā)。
