由於前段時間開發出來的vue版本的聊天頁,性能、用戶體驗等方面十分不盡人意,故開啟了新的征途,nvue版本聊天頁的開發。
痛點一、進入頁面保持在最底部
這次重構nvue版本的聊天頁,使用了標新立異的渲染方式。眾所周知,前端渲染頁面都是由上而下渲染的,那么如果需要進入頁面的時候,便保持在頁面的最底部,就需要等待頁面渲染完畢后跳轉至最底部。這樣的渲染方式就會導致在進入頁面時,用戶能很明顯的感受到頁面抖動了一下(可能多次)。
所以此次重構,博主選擇將整個頁面旋轉180度,原本的最頂部,變成了頁面的最底部,進入頁面無需滾動到最底,用戶視角里頁面會固定在底部,且渲染消息是自下而上渲染。具體css代碼如下:
/* 由於nvue中不支持全部的css,需要將這段樣式寫進對應dom元素的style上 */ direction: rtl; transform: rotate(180deg); -ms-transform: rotate(180deg); -moz-transform: rotate(180deg); -webkit-transform: rotate(180deg); -o-transform: rotate(180deg);
痛點二、進入頁面有長時間白屏
原先的vue版本聊天頁,在進入頁面時,會有長時間的白屏。后來博主將其中onLoad鈎子中所做的大部分計算操作,轉移到onReady中,白屏時間也優化了蠻多。
現在,使用nvue版本的聊天頁,建議uniapp原生的頂部導航欄,渲染速度快,不會出現白屏。具體配置在pages.json中。
{ "path": "pages/xxx/xxx", "style": { "titleNView": { "autoBackButton":false, "buttons": [ { "float":"left", "fontSize": "46rpx", // iconfont自定義按鈕寫法 "fontSrc": "/style/iconfont/iconfont.ttf", "text": "\ue61d" }, { "float":"right", "fontSize": "46rpx", "fontSrc": "/style/iconfont/iconfont.ttf", "text": "\ue68d" } ] }, "transparentTitle": "none", "navigationBarTextStyle": "xxxx", "navigationBarTitleText": "xxxx", "navigationBarBackgroundColor": "xxxx" } }
痛點三、彈出鍵盤,切換表情框頁面閃動嚴重
在原先的vue版本聊天頁中,彈出鍵盤,切換表情框會導致頁面需重新計算彈出軟鍵盤或表情框后頁面的位置(保持用戶在看的消息的位置)。
在對聊天頁進行180度顛倒渲染后,彈出鍵盤、表情框的時候,就無需對其頁面的位置去做重新計算了,但需要在彈出鍵盤、表情框的時候,撐高底部欄。比如寫個計算屬性computed:
<template> <!-- 滾動區域 --> <scroller>xxxx</scroller> <!-- 底部區域 --> <div :style="footerHeight"></div> </template> <script> export default { computed: { footerHeight() { if (彈出鍵盤) { return `${鍵盤高度}rpx`; } else if (彈出表情框) { return '450rpx'; } else { return '0'; } } } } </script>
痛點四、消息富文本渲染
作為一個聊天軟件,@人、自定義表情(圖片)、普通文本、鏈接都是需要去做個性化的自定義。在原本的vue版本聊天頁中,這些事情均交由uParse去處理。
轉為nvue開發后,uParse不兼容,以博主親身體驗嘗試來講,只有rich-text組件和mp-html插件能使用上。但是!這兩個東西都有它的問題,rich-text組件,在ios端設置其內部節點的樣式會不生效,已報BUG;而mp-html插件,首先渲染采用的webview,比weex渲染慢,其次就是iOS端使用該插件,無法加載本地圖片(表情)。
所以博主最后放棄了這兩個選項,改為planC,自己寫富文本消息解析,通過大致計算文本的寬度,將文本表情鏈接等拆分成一塊塊元素拼接成一條消息。
痛點五、各種兼容細節
1.使用textarea不能使用auto-height屬性,在iOS端會導致textarea無法滾動。
2.使用textarea不能使用v-model,盡管綁定v-model在nvue版本的iOS端不會出現吞字的問題,但是在Android端會出現無法長按刪除的問題,所以只能使用value。
3.textarea組件的blur事件中沒有cursor(光標位置)參數。
4.nvue中無法使用main.js中掛載的全局變量,需要在頁面內再次單獨引入。
5.nvue頁面中能直接使用vuex,但是頁面內引用的js文件中,無法訪問vuex(訪問的state為初始值)。若需要在其內引用的js中也使用vuex,則需要在nvue頁面中,將其$store傳進js文件中。
6.官方推薦nvue中長列表使用list組件,但是list組件在iOS端下拉加載歷史消息的時候,存在卡頓的現象,故博主推薦的是使用scroller組件,其配置項跟list一致。
7.在iOS端和Android端長按textarea,是不同的表現,iOS端會彈出鍵盤,而Android端不會彈出鍵盤,而是彈出上下文菜單。
8.使用dom.scrollToElement這個API,設置其offset值在iOS端和Android端的表現不一致。
9.下拉加載更多功能在iOS端需要做限制操作,兩次加載更多觸發的時間差最好不小於1.5s,因為iOS端滾動有回彈的效果。
總結
其實還有很多細節點的問題,比如樣式問題等沒有羅列出來。繼續加油,keep learning…