日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

uniapp开发聊天APP踩坑记录

發布時間:2024/3/12 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 uniapp开发聊天APP踩坑记录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

最近工作重心轉移到了uniapp上,有一說一,這個框架跨端確實牛逼,一套代碼能一次編譯到多端使用。但隨之而來的兼容性問題也是層出不窮,同樣的在面臨APP底層的改動也顯得力不從心。同時,uniapp的性能問題也是一直被人所詬病的一點,這個點上一還是要提高自己本身的編碼能力,二還是得依靠dcloud團隊能持續優化框架。
本篇博客是記錄使用uniapp開發一個聊天APP的踩坑問題。

一、輸入框吞字,光標閃動問題

uniapp中使用輸入框,無論是input組件還是textarea組件,都存在一個問題。就是如果組件綁定v-model的話,輸入的時候在蘋果手機或者部分特殊的有待選區域的輸入法,會存在輸入框吞字,從文字中間輸入時光標會閃動到最后的兩個BUG。
該問題的解決方案,最終只能使用:value去綁定輸入框,為輸入框分配兩個變量,一個真實的value值,一個是臨時的tempValue值。臨時tempValue值用于在輸入觸發的@input事件內實時接收,真實的value值只在第一次由無值到有值的時候接收一次,而后只需在發送的時候設置真實value值為空即可清空輸入框。

<template><textarea :value="value" @input="handleInput"></textarea><button @click="handleClickSend">發送</button> </template>export default {data: {value: '',tempValue: ''}handleInput(event) {const value = event.detail.valueif(!this.value) {// 第一次值為空時賦給真實值this.value = value}this.tempValue = value // 臨時值用于實時接收}async handleClickSend() {if(!this.value) {return}// 發送時,臨時值存儲的為當前輸入框內的值// 隨后將真實value值設置為空實現清空輸入框// 模擬發送請求const res = await this.$axios.post({url: xxxx,text: this.tempValue })this.value = '' // 清空輸入框} }

二、組件key值問題

博主封裝了一個消息氣泡渲染組件,只需要將必要的參數傳遞進去即可渲染各種消息,但是在開發過程中,發現了氣泡消息拋出來長按事件所帶的參數錯亂的問題,后經研究為組件加上了key值才解決。

<template><view class="chat-warp" v-for="item of msgList" :key="item.id"><!-- 注意,需要給組件也給key值 --><chat-item :item="item" :key="item.id"></chat-item></view> </template>

可能是vue中對組件的更新機制不同,所以v-for循環中的組件也需要給key值。

三、消息定位問題

項目中的聊天頁,使用的是scroll-view配合封裝好了的富文本組件來渲染各種消息,由于下拉加載更多消息時總會有屏幕閃動的現象出現,故最后是兩層scroll-view來配合使用,一層是真消息,一層是假消息。加載更多時,假消息顯示真消息隱藏,等到消息完全渲染定位完畢后再隱藏假消息、顯示真消息。

(1)滾不到最底部的問題

在開發的過程中,常常遇到發送消息時,滾不到最底部;亦或者進入聊天頁時,滾不到最底部的情況。
針對此,一開始是不斷地瞄點滾動到底部,一進入頁面就會觸發七八次goBottom函數。
后經過優化,整理了思路,改成了判斷消息是否完全渲染完畢后,再執行goBottom函數。而判斷消息是否完全渲染完畢,則需要用到uni.createSelectorQuery()這個API。

// 在onReady鉤子中調用goBottom onReady() {this.$nextTick(() => {this.goBottom()}) } // 滾動到底部函數 goBottom() {this.scrollView = '' // scrollview瞄點置空this.$nextTick(async () => {const res = await this.checkMsgIsRender('btm') // 檢測最底部的消息是否完全渲染完畢if(res) {this.scrollView = 'bottom' // 瞄點至底部} else {this.goBottom()}}) } // 檢測消息是否渲染完畢 checkMsgIsRender(position) {let msgID = ''if(position === 'btm') {// 底部// 找到最底部的消息IDmsgID = xxxx} else {// 頂部// 找到最頂部的消息IDmsgID = yyyy}// 返回一個Promisereturn new Promise((resolve) => {const query = uni.createSelectorQuery().in(this)query.select('#id').boundingClientRect(data => {// 存在data,且存在寬和高,視為渲染完畢if(data && data.width && data.height) {resolve(true)} else {resolve(false)}}).exec();}) }

(2)下拉加載更多消息瞄點定位不準的問題

同樣的,下拉加載更多消息也是存在有瞄點不準確的問題,而一開始的解決方案,是簡單粗暴的延時兩秒鐘,這直接導致了用戶等待的時間過長的問題出現,且還不一定能準確的定位到。
參照了滾動到底部的做法,博主舉一反三,也通過判斷消息是否完全渲染完畢來決定瞄點的時機,以確保瞄點定位準確。

// 加載更多 async loadMore() {await this.getMoreMsg() // 向服務器獲取更多消息或者展示本地消息,該函數不展開let location = async () => {const res = await this.checkMsgIsRender('top') // 檢測最頂部的消息是否完全渲染完畢if(res) {// 這里還需要找到需要瞄點過去的消息ID,zzzzthis.scrollView = zzzz // 瞄點到消息zzzz} else {location ()}}this.scrollView = '' // scrollview瞄點置空this.$nextTick(() => {location ()}) }

總結

其實呢,網上一直存在有聲音在詬病uniapp,但是講句道理,能夠以一套代碼運行到多端的技術還是挺牛逼的,盡管目前來說這項技術還不是很成熟(性能問題、兼容問題)。
uniapp能帶領我們的項目走向多遠,其實還是可以期待的,當然不能光指望dcloud團隊,個人代碼的寫法也很關鍵,繼續努力吧…

總結

以上是生活随笔為你收集整理的uniapp开发聊天APP踩坑记录的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。