小程序模板網(wǎng)

小程序瀑布流的實踐

發(fā)布時間:2020-05-15 10:18 所屬欄目:小程序開發(fā)教程

前言:最近在工作中,實踐了下在 微信小程序中實現(xiàn)瀑布流列表(左右兩欄,動態(tài)圖文) ,最終的效果還不錯,所以在此記錄,僅供有需要的人參考。

最終的效果:

補充說明的是,要做瀑布流,最好是可以知道圖片的高度,由接口下發(fā),來提前占位,否則,即使是原生app,也會因為圖片的加載閃屏使得不好的用戶體驗。在小程序中,沒有原生app的流式layout控件,所以不知道圖片寬高的情況下,只能減少每一頁的page_size,在加載完圖片之后,再計算插入的位置(對產(chǎn)品來說,這可能是一個不可接受的漫長過程)

嘗試過的小程序瀑布流實現(xiàn)方式

1.左右兩列判斷奇偶性渲染

//demo.js

Page({
    data:{
        renderLists:[]
    },
    fetchData(){
        request(url,params).then(res=>{
            const PreData=this.data.renderLists
            this.setData({
                renderLists:PreData.concat(res)
            })
        })
    }
})
//demo.wxml
<view class="waterfall">
    <view class="waterfall__left">
        <your-compoent 
            wx:for="{{renderLists}}"
            wx:key="id"
            wx:if="{{index % 2 === 0}}"
        />
    </view>
    <view class="waterfall__right">
        <your-compoent 
            wx:for="{{renderLists}}"
            wx:key="id"
            wx:if="{{index % 2 === 1}}"
        />
    </view>
</view>
說明 優(yōu)點 缺點
左右列重復(fù)wx:for 渲染數(shù)據(jù),根據(jù)index索引的奇偶性來wx:if 簡單 1.重復(fù)for循環(huán)。2.如果每個item高度相差較大,很容易造成左右矮的那一欄是部分空白的

或許京東購物小程序-首頁就是這樣做的?(不確定)

2.絕對定位

這個方式可能就是目前pc端的實現(xiàn)方式,原理都一樣。但是在小程序中,有以下幾個需要解決的問題

  1. 如果列表是動態(tài)圖文,即使知道圖片寬高,如何獲取文字內(nèi)容區(qū)域的高度?
  2. 安卓下實驗過會出現(xiàn)白屏,卡頓等性能問題(這個問題導(dǎo)致直接放棄了這個做法)

3.左右兩列計算插入渲染

//demo.js

Page({
    data:{
        leftLists:[],
        rightLists:[]
    },
    onLoad(){
        this.leftHeight=0
        this.rightHeight=0
    },
    fetchData(){
        request(url,params).then(res=>{
            this.generate(res)
        })
    },
    generate(list){
        let leftList=[],rightList=[]
        list.map(async (item)=>{
            //每個item的高度=圖片寬高+內(nèi)容區(qū)域
            const itemHeight=getImageHeight(item)+getContentHeight(item)+gap
            this.leftHeight>this.rightHeight?rightList.push[item]:leftList.push(item)
        })
        this.render({leftList,rightList})
    },
    getImageHeight(){
        //如果知道圖片寬高,就return item.height
        //如果不知道,wx.getImageInfo(需要配合域名)或者通過display:"node" image 然后 bindload。
    },
    getContentHeight(){
        //文字內(nèi)容區(qū)域高度固定,直接返回
        //不固定,做數(shù)據(jù)映射,例如10個字一行,行高按照設(shè)計稿,做rpxToPx返回
    },
    render(params){
        const {leftList,rightList}=params
        const preLeft=this.data.leftList;
        const preRight=this.data.rightList
        this.setData({
            leftList:preLeft.concat(leftList),
            rightList:preRight.concat(rightList)
        },()=>{
             const query = this.createSelectorQuery(); 
       query.select('.wrapper__left').boundingClientRect();
      query.select('.wrapper__right').boundingClientRect(); 
           query.exec((res) => {
             this.leftHeight = res[0].height; 
             this.rightHeight = res[1].height;
           });
        })
    }
})
//demo.wxml
<view class="waterfall">
    <view class="waterfall__left">
        <your-compoent 
            wx:for="{{leftLists}}"
            wx:key="id"
        />
    </view>
    <view class="waterfall__right">
        <your-compoent 
            wx:for="{{rightLists}}"
            wx:key="id"
        />
    </view>
</view>
說明 優(yōu)點 缺點
下面↓↓↓ 性能好,實現(xiàn)的效果好 (⊙o⊙)…
注意下面的操作都必須是一個同步獲取的過程,需要異步獲取的都要async await,如果需要異步獲取的數(shù)據(jù)多,例如圖片,那就是一個耗時操作
可能有小概率會影響我們的計算,這個問題是存在的且可以接受的
createSelectorQuery

可以看下小程序 附近的餐廳 ,效果很好,他的圖片寬高是服務(wù)器返回的,文字內(nèi)容區(qū)域是固定的(標題只有幾個字,也是兩行)

結(jié)論

目前來說,第三種方案的實現(xiàn)效果最好,也是我們正在線上使用的方式,推薦使用。


易優(yōu)小程序(企業(yè)版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://22321a.com/wxmini/doc/course/25182.html 復(fù)制鏈接 如需定制請聯(lián)系易優(yōu)客服咨詢:800182392 點擊咨詢
QQ在線咨詢