最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • uniapp小程序实现瀑布流布局

    正文概述 掘金(林深鹿)   2021-04-05   1499

    一、前言

    现在写瀑布流算不算是炒冷饭啊?

    我不管, 我就要写,谁也别想拦我。

    瀑布流应该算是很常见的一种布局方法了,大致的思路也很好理解, 但是在小程序里面确有另外需要考虑的几个问题。

    问题1:uniapp是基于Vue的,所以不好直接操作DOM。

    问题2:uniapp基于Vue,但也做了一些修改,所以不好拿ref来操作

    二、先说思路

    为了保证文章的长度,以及有些小伙伴对瀑布流的基本思路不是很了解,所以先讲讲瀑布流的思路,先看下图。

    uniapp小程序实现瀑布流布局

    可以看到,商品的图片高度是不一致的,再加上商品标题的行数不一致,最终呈现的效果是交错排列的。

    之前在开发过程中,我也试过用CSS的Flex布局,Column布局来实现,勉强能实现同样的效果,但是最终对接后台要考虑商品的热度优先,所以只能放弃。

    Flex实现缺点:使用Flex布局并不能准确计算高度来插入商品。

    Column实现缺点:使用Column布局不好操作先后顺序。

    三、核心代码

    如题,本文对于瀑布流的实现是基于uniapp开发小程序的,如果期望JS原生实现,本文的很多思路是需要修改的。

    先解答部分疑惑:

    // component/waterfall.vue
    <template>
        <view class="waterfall">
            <view hidden>
                // 用JS原生实现时可以直接用for循环插入,然后获取列高度
                // 这里通过载入图片调用方法, 默认传参带有图片信息,可以获得图片高度
                <block v-for(item in imgList" :key="item.id">
                    <image :src="item.url" @load="loadImg" ></iamge>
                </block>
            </view>
            <view class="list" v-for="(list, key) in waterfall" :key="key">
                <navigator url="https://www.baidu.com" v-for="item in list.list" :key="item.id">
                    <image :src="item.url" mode="widthFix"></image>
                    <view class="shop-info">
                        /* 标题等信息,略 */
                    </view>
                </navigator>
            </view>
        </view>
    </template>
    
    <script>
        export default {
            // 抽出为单独的组件,所以数据来源于父组件传递,也可以是当前组件请求API
            props: { imgList: Array },
            data(){
                return {
                    lists: [], // 备份imgList用的数组,方便操作
                    waterfall: [
                        // 用于记录当前列的高度,不在方法中保存是为了上拉获取新数据也能使用
                        // 因为默认手机显示,可以固定两列
                        // 如果是做自适应或者电脑端多列,可以动态插入实现多列
                        {
                            height: 0, 
                            list: []
                        },{
                            height: 0, 
                            list: []
                        }
                    ]
                }
            },
            created(){
                this.lists = this.imgList; // Vue创建data后立即备份
            },
            watch(){
                // 监听数据源,如果有新值传入,则用lists数组备份
                imgList(data){ data.length && this.lists.push(...data); }
            },
            methods: {
                loadImg(ev){
                    let Root = this.waterfall;
                    let height = e.detail.height;
                    // 根据当前高度决定将新数据给谁,并更新列高度;优先插入左侧
                    if(Root[0].height <= Root[1].height){
                        // 考虑热度优先的问题, 所以用的是shift()方法推出头部数据。
                        Root[0].list.push(this.lists.shift())
                        Root[0].height += height;
                    } else {
                        Root[1].list.push(this.lists.shift())
                        Root[1].height += height;
                    }
                }
            }
        }
    </script>
    

    至此,核心代码就完成了。

    四、总结

    希望如果有小伙伴看完这篇文章之后,决定使用这个方法时,能记得一件事,这个写法可能有性能问题方面的影响,能在这方面下功夫去深入研究下。

    我发布出来,只是想写一篇萌新也能看得懂的文章, 但不代表这就是最终的方案。


    起源地下载网 » uniapp小程序实现瀑布流布局

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元