手机版

小程序瀑布流的实践

时间:2021-12-03 来源:互联网 编辑:宝哥软件园 浏览:

最近在工作中,我在微信小程序中实现了瀑布流列表(左右栏、动态图文),最终效果还不错,所以在这里记录下来,仅供有需要的人参考。

最终效果:

小程序瀑布流的实践(图1)

另外,要做瀑布流,最好知道图片的高度,这是界面发送来提前占用空间的。否则,即使是原生应用也会因为画面闪烁而导致用户体验不佳。在小程序中,没有原生app的流式布局控件,所以如果不知道图片的宽度和高度,只能先缩小每页的page_size,然后在加载图片后再计算插入位置(这对于产品来说可能是一个无法接受的漫长过程)。

ding: 0px; font-size: 18px; border: 0px; font-weight: normal; font-family: "Helvetica Neue", Helvetica, Tahoma, Arial, STXihei, "Microsoft YaHei", 微软雅黑, sans-serif; line-height: 1.6em; color: rgb(51, 51, 51); text-rendering: optimizelegibility; text-indent: 1em; background-color: rgb(254, 254, 254);">尝试过的小程序瀑布流实现方式

1.左右两列判断奇偶性渲染

//demo.jsPage({    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>
说明优点缺点左右列重复wx:for 渲染数据,根据index索引的奇偶性来wx:if简单1.重复for循环。2.如果每个item高度相差较大,很容易造成左右矮的那一栏是部分空白的

或许京东购物小程序-首页就是这样做的?(不确定)

小程序瀑布流的实践(图2)

2.绝对定位

这个方式可能就是目前pc端的实现方式,原理都一样。但是在小程序中,有以下几个需要解决的问题

  1. 如果列表是动态图文,即使知道图片宽高,如何获取文字内容区域的高度?
  2. 安卓下实验过会出现白屏,卡顿等性能问题(这个问题导致直接放弃了这个做法)

3.左右两列计算插入渲染

//demo.jsPage({    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的高度=图片宽高+内容区域            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(){        //文字内容区域高度固定,直接返回        //不固定,做数据映射,例如10个字一行,行高按照设计稿,做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>
说明优点缺点下面↓↓↓性能好,实现的效果好(⊙o⊙)…
注意下面的操作都必须是一个同步获取的过程,需要异步获取的都要async await,如果需要异步获取的数据多,例如图片,那就是一个耗时操作可能有小概率会影响我们的计算,这个问题是存在的且可以接受的createSelectorQuery

可以看下小程序附近的餐厅,效果很好,他的图片宽高是服务器返回的,文字内容区域是固定的(标题只有几个字,也是两行)

小程序瀑布流的实践(图3)

结论

目前来说,第三种方案的实现效果最好,也是我们正在线上使用的方式,推荐使用。

版权声明:小程序瀑布流的实践是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。