您好,登錄后才能下訂單哦!
最近做了一些小程序方面的性能優化,如分包加載,添加骨架屏等,這次主要說一下骨架屏的相關內容。
關于骨架屏,有三種方法:
1.直接請UI同學幫忙P張圖,當做loading圖放上去。這種方法簡單粗暴,但是需要請人幫忙~
2.根據每個頁面,自己寫一套相同的代碼來覆蓋樣式。這種方法的工程量,你懂的~
3.能不能寫個組件呢?該組件自動獲取元素位置大小信息來渲染,數據返回后將其卸載。
下面主要說第三種方法~
主框架采用taro,一套代碼兼容多端,但是今天這個代碼,需要考慮兼容性~
根據上面的思路,我們首先要找到骨架屏的容器,然后找到需要P成灰色的元素,獲取該元素的位置大小信息,最后就是渲染了~
獲取元素,taro提供了API,Taro.createSelectorQuery()。通過這個API返回一個SelectorQuery對象實例,然后再通過selectAll()來查找骨架中帶有特定類的class名,查找之后通過boundingClientRect()獲取元素的位置大小信息,把這些信息存放在數組中。
我這邊寫了兩個類,一個是skeleton-radius,渲染圓形;一個是skeleton-rect,渲染長方形。后續大家可以自行擴展。
文字有點多,大家可能看著有點云里霧里的,下面上代碼~
// 百度小程序目前不支持跨自定義組件的后代選擇器: >>> // 但是H5使用后代選擇器(.the-ancestor .the-descendant)的時候,可以自動識別自定義組件內的后代 // 微信小程序支持跨自定義組件都后代選擇器(.the-ancestor >>> .the-descendant),可修改為如`.${this.props.selector} >>> .${this.props.selector}-radius` if (process.env.TARO_ENV === 'weapp') { Taro.createSelectorQuery().selectAll(`.${this.props.selector} >>> .${this.props.selector}-radius`) .boundingClientRect().exec(rect => { that.setState({ radiusList: rect[0] }); }); } else { Taro.createSelectorQuery().selectAll(`.${this.props.selector} .${this.props.selector}-radius`) .boundingClientRect().exec(rect => { that.setState({ radiusList: rect[0] }); }); }
大家也看到上面的注釋了,如果要在多端運行,可先判斷環境,根據環境使用不同的選擇器。上面代碼是實現一個圓形的灰色區域~大家如果有多個形狀的需求的話,可以簡單封裝一個函數,這里我就不再細說了,具體的可以到Demo詳細查看~
細說一下后代選擇器的兼容性問題:
接下來就是渲染了,這個比較簡單,直接上代碼~這里背景色和將要P成條狀等的元素的背景色都可以在使用組件時自定義傳入,也可以不傳,有默認色~
<View className='skeleton-container' style={{background: `${bgColor}`}}> { radiusList.map(radiusItem => ( <View className='skeleton-item skeleton-item-radius' style={{width: `${radiusItem.width}PX`, height: `${radiusItem.height}PX`, background: `${itemColor}`, top: `${radiusItem.top}PX`, left: `${radiusItem.left}PX`}} /> )) } { rectList.map(rectItem => ( <View className='skeleton-item' style={{width: `${rectItem.width}PX`, height: `${rectItem.height}PX`, background: `${itemColor}`, top: `${rectItem.top}PX`, left: `${rectItem.left}PX`}} /> )) } </View>
到這里,組件已經完成了,使用的時候可以直接引入組件,然后傳入selector就可以了,注意,由于數據是動態獲取的,頁面開始為空,這里就需要mock一些假數據來填充頁面了~要覆蓋的元素類名必須和組件中的圖形類保持一致~
<View className='container' style={{fontSize: '20PX'}}> { showSkeleton && <Skeleton selector='skeleton' bgColor='pink' itemColor='skyblue' /> } <View className='skeleton'> <View className='userInfo'> <Image src={userInfo.avatarUrl} alt='用戶頭像' className='userInfo-avatar skeleton-radius' /> <Text>{userInfo.nickName}</Text> </View> <View> { list.map(item => ( <View className='skeleton-rect' style={{marginBottom: '30PX'}}>{item}</View> )) } </View> {/* 自定義組件外層最好沒有元素包裹,否則微信小程序無法識別,但是H5可以識別 */} <List /> </View> </View>
看到注釋了嗎?使用自定義組件時一定要注意噢~自定義組件若被元素報錯,微信小程序無法識別到自定義組件內的圖形類!!!
最后要說一下適合使用骨架屏的場景:頁面結構簡單,元素的寬高固定~若元素寬高不固定的話,你寫的mock假數據可能和實際渲染出來的頁面差距較大,例如瀑布流~
好了,這次的一些收獲就到這里了~大家如果有更好的方法,可以留言交流~最后,附上完整的代碼地址~
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持億速云。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。