欢迎来到本网站

全国统一咨询热线:158-2196-7367

新闻中心

新闻中心News Center

联系方式

联系方式Contact infoemation

电话:158-2196-7367

邮箱:amy@hanett.com

地址:中国·上海市金山区朱泾镇南横街4号4幢1296室H座

当前位置:明翔网络 > 行业新闻 > 小程序瀑布流的实践

小程序瀑布流的实践

文章出处:http://www.ucunicom.com/a/1018.html 阅读量:16 发表时间:04-21 15:10
行业新闻

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

最终的效果:

补充说明的是,要做瀑布流,最好是可以知道图片的高度,由接口下发,来提前占位,否则,即使是原生app,也会因为图片的加载闪屏使得不好的用户体验。在小程序中,没有原生app的流式layout控件,所以不知道图片宽高的情况下,只能减少每一页的page_size,在加载完图片之后,再计算插入的位置(对产品来说,这可能是一个不可接受的漫长过程)

尝试过的小程序瀑布流实现方式

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.绝对定位

这个方式可能就是目前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

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

结论

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

全国咨询热线:158-2196-7367

二维码

地址:中国·上海市金山区朱泾镇南横街4号4幢1296室H座

版权所有 © 1999-2017 Copyright © 1999-2017 All Rights Reserved

cache
Processed in 0.003663 Second.