本文章是一個(gè)系列文章,以一個(gè)完整的可用于生產(chǎn)的實(shí)際項(xiàng)目探索微信小程序開(kāi)發(fā)中我們經(jīng)常會(huì)遇到的問(wèn)題,希望能提供完美的解決方案,這次是本系列文章的第二篇了,以下列出該系列文章鏈接。
- 微信小程序及h5,基于taro,zoro最佳實(shí)踐探索
- 微信小程序電商實(shí)戰(zhàn)-登錄模塊設(shè)計(jì)
- 微信小程序電商實(shí)戰(zhàn)-自定義頂部導(dǎo)航欄
工作忙碌,難得有時(shí)間繼續(xù)開(kāi)發(fā)研究這個(gè)項(xiàng)目,目前完成了,基礎(chǔ)設(shè)施開(kāi)發(fā)及首頁(yè)得開(kāi)發(fā),話不多說(shuō),老規(guī)矩,先來(lái)看下效果吧

這是根據(jù)頁(yè)面布局自動(dòng)生成得骨架屏,目前非常流行的一種提升體驗(yàn)的辦法
為了能看到骨架屏的渲染,我調(diào)慢了所有接口的響應(yīng)速度,因此演示響應(yīng)較慢

整體效果還不錯(cuò)吧(沾沾自喜中~)
骨架屏的思路
骨架屏的實(shí)現(xiàn)思路相對(duì)較簡(jiǎn)單,使用方法也很方便
我們知道微信小程序已經(jīng)開(kāi)發(fā)了選擇器功能,可以利用此特性獲取到dom節(jié)點(diǎn),為了能讓骨架屏組件知道該如何繪制,我們需要做如下約定:
- 約定.skeleton樣式類為骨架屏查找繪制節(jié)點(diǎn)的根節(jié)點(diǎn)
- 約定.skeleton-square樣式類,表示繪制當(dāng)前節(jié)點(diǎn)的骨架節(jié)點(diǎn)樣式為方形(如商品卡片)
- 約定.skeleton-circular樣式類,表示繪制當(dāng)前節(jié)點(diǎn)的骨架節(jié)點(diǎn)為圓形(如logo)
- 約定.skeleton-cylinder樣式類,表示繪制當(dāng)前節(jié)點(diǎn)的骨架節(jié)點(diǎn)為長(zhǎng)條形(如搜索框)
- 約定.skeleton-light與.skeleton-dark為塊元素背景骨架樣式
骨架屏的使用
首先我們需要引入skeleton組件到頁(yè)面中,并且在頁(yè)面根元素上加上.skeleton樣式
<View className={classNames(styles.home, 'skeleton')}>
{initialize && <ComponentCommonSkeleton />}
</View>
然后在對(duì)應(yīng)元素中加入不同的樣式類,繪制骨架
<View className={classNames(styles.hotsale, 'skeleton-light')}>
<View className={styles.header}>
<View className={classNames(styles.title, 'skeleton-square')}>
今日熱賣
</View>
<View className={classNames(styles.tip, 'skeleton-square')}>
每日推薦,超值搶購(gòu)
</View>
</View>
</View>
骨架屏的實(shí)現(xiàn)
完整的實(shí)現(xiàn)邏輯,由于代碼較多,不與全部給出,有興趣的直接去倉(cāng)庫(kù)吧skeleton源碼
我們來(lái)看一下關(guān)鍵代碼,如何獲取骨架節(jié)點(diǎn)
// 利用微信小程序的selectorQuery查找相關(guān)節(jié)點(diǎn)
selectAll = selector =>
new Promise(resolve =>
Taro.createSelectorQuery()
.selectAll(selector)
.boundingClientRect()
.exec(res => resolve(res[0])),
)
componentDidMount() {
const { selector } = this.props
// 利用微信小程序跨自定義組件選擇器`>>>`獲取節(jié)點(diǎn)信息
Promise.all([
this.selectAll(`.${selector} >>> .${selector}-light`),
this.selectAll(`.${selector} >>> .${selector}-dark`),
this.selectAll(`.${selector} >>> .${selector}-square`),
this.selectAll(`.${selector} >>> .${selector}-circular`),
this.selectAll(`.${selector} >>> .${selector}-cylinder`),
]).then(([lights, darks, squares, circulars, cylinders]) =>
// 存儲(chǔ)節(jié)點(diǎn)信息,用于渲染骨架屏
this.setState({
lights,
darks,
squares,
circulars,
cylinders,
}),
)
}
獲取到了相關(guān)節(jié)點(diǎn)信息,比如width,height,top,left等信息后,便可以利用絕對(duì)定位或者fixed繪制骨架了
當(dāng)然這只能解決常駐組件的獲取,對(duì)于一些動(dòng)態(tài)組件,比如列表渲染我們?cè)撊绾翁幚砟?,這里是一個(gè)比較麻煩的問(wèn)題,我們需要在數(shù)據(jù)還未獲取之前,給列表數(shù)據(jù)設(shè)置部分默認(rèn)數(shù)據(jù)
比如: 設(shè)置默認(rèn)的props或者state,這樣項(xiàng)目初始化時(shí)便會(huì)渲染默認(rèn)數(shù)據(jù),也就可以獲取到節(jié)點(diǎn)了
該項(xiàng)目托管于github,如有需要,請(qǐng)自取weapp-clover,感謝關(guān)注,感謝star