uniapp小程序实现瀑布流布局的思路与代码

一、前言

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

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

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

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

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

二、先说思路

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

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

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

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

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

PS:如果对产品排序没有要求的话, 可以考虑纯CSS实现,这里不多赘述,掘金里很多的。

三、核心代码

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

因为无法通过$refs获取到列的高度,所以代码是通过Image标签的@load时间先加载一次图片,并将图片的宽高等信息传递给方法。

// 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>

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

PS:因为要借由image的@load事件来触发方法,所以大量加载势必会影响性能,所以要自己做点取舍了。

四、总结

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

到此这篇关于uniapp小程序实现瀑布流布局的思路与代码的文章就介绍到这了,更多相关uniapp小程序瀑布流布局内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • 分析uniapp如何动态获取接口域名

    背景 接口域名没有写死,而是动态获取.具体实现就是 通过读取一个静态json文件,来设置真实的接口域名.好处是原域名有可能被封,这样可以直接后台操作修改该配置文件即可:不然的话,h5 项目可能还好说,app 的话必须重新发版. 代码 // httpService.js 对 uni.request 的封装. 在数据请求入口处,统一先进行 域名获取,即 执行 config.requestRemoteIp 方法 import config from '@/config' import Vue from

  • uniapp H5 https跨域请求实现

    什么是跨域 跨域是浏览器的专用概念,指js代码访问自己来源站点之外的站点.比如A站点网页中的js代码,请求了B站点的数据,就是跨域. A和B要想被认为是同域,则必须有相同的协议(比如http和https就不行).相同域名.和相同端口号(port). 如果你是做App.小程序等非H5平台,是不涉及跨域问题的. 由于uni-app是标准的前后端分离模式,开发h5应用时如果前端代码和后端接口没有部署在同域服务器,就会被浏览器报跨域. 本文主要介绍uniapp H5开发中,本地调试https的接口实现跨

  • uniapp微信小程序实现一个页面多个倒计时

    本文实例为大家分享了uniapp实现一个页面多个倒计时的具体代码,供大家参考,具体内容如下 设计图(需求) 在这里插入图片描述 结构 <view class="group-list" v-for="item in message" :key="item.productId"> <view class="group-img" @click="navTo"> <image :src

  • uniapp电商小程序实现订单30分钟倒计时

    本文实例为大家分享了uniapp实现订单30分钟倒计时的具体代码,供大家参考,具体内容如下 倒计时函数如下: // cm 参数是截至时间-当前时间 // 截至时间是后台返回的数据,当前时间通过new Date() 的方式进行获取 runBack(cm) { if (cm > 0) { // 如果时间是超过1分钟,则需要展示的样式是: x分x秒,如果是小于1分钟,则是 00分x秒 cm > 60000 ? (this.rocallTime = (new Date(cm).getMinutes()

  • 关于uniApp editor微信滑动问题

    uniapp 小程序在微信下会出现类似下拉问题 解决方法是在app.vue 的页面onLaunch方法内添加禁止下滑方法 this.$nextTick(() => { document.body.addEventListener("touchmove", this.addBodyTouchEvent, { passive: false }); }); 问题解决后在uniApp的editor组件内无法滑动 解决方法 data内添加这两个值 添加touchstart和touchend

  • uniapp实现可滑动选项卡

    本文实例为大家分享了uniapp实现可滑动选项卡的具体代码,供大家参考,具体内容如下 tabControl-tag.vue <template name="tabControl"> <scroll-view scroll-x="true" :style="'background-color:'+bgc+';top:'+top+'px;'" :class="fixed?'fxied':''" :scroll-l

  • uniapp微信小程序:key失效的解决方法

    uniapp 代码 <template> <view> <image v-for="(item, i) in fileList" :key="item[urlKey]" :src="item[urlKey]"></image> </view> </template> <script> export default { props: { urlKey: {defau

  • uniapp开发小程序实现滑动页面控制元素的显示和隐藏效果

    前言 实现思路:通过小程序API中的触摸事件,配合CSS来实现元素的显示和隐藏.ps(也想过另一种通过监听页面滚动的方式来实现,不过效果一定很差0.0) 一.需要用到的事件touchmove.touchend 二.话不多说上代码 1.看需求,如果是整个屏幕滑动后元素发生变化,最好放在最外面的view 代码如下: <view class="container" @touchmove="handletouchstart" @touchend="handl

  • 详解uniapp的全局变量实现方式

    前言 本文整理了一些uniapp全局变量的实现方式,细节知识来自于uView官网中对uniapp中的全局变量实现,感兴趣的同学可以前往uView官网搜索vuex进行查看 全局变量的实现方式 一般来说在uniapp中有以下几种方式 本地存储 配置文件 挂载到 Vue.prototype globalData vuex 下面对这5种方式的实现进行介绍 本地存储 永久存储,以app为例即使该应用被关闭,该数据依然会被存储 这是一种永久的存储方式,类似于web的Local Storage(有关于Cook

  • uniapp小程序实现瀑布流布局的思路与代码

    一.前言 现在写瀑布流算不算是炒冷饭啊? 我不管, 我就要写,谁也别想拦我. 瀑布流应该算是很常见的一种布局方法了,大致的思路也很好理解, 但是在小程序里面确有另外需要考虑的几个问题. 问题1:uniapp是基于Vue的,所以不好直接操作DOM. 问题2:uniapp基于Vue,但也做了一些修改,所以不好拿ref来操作 二.先说思路 为了保证文章的长度,以及有些小伙伴对瀑布流的基本思路不是很了解,所以先讲讲瀑布流的思路,先看下图. 可以看到,商品的图片高度是不一致的,再加上商品标题的行数不一致,

  • uniapp小程序使用RSA加密解密的操作代码

    1.安装wxmp-rsa npm i wxmp-rsa -S 2.新建rsa.js文件 import WxmpRsa from 'wxmp-rsa' //公钥和私钥换自己的 // 定义公钥 const publicKey = ` -----BEGIN PUBLIC KEY----- MIGeMA0GCSqGSIb3DQEBAQUAA4GMADCBiAKBgFnWSUwsmGawhMJ30z6y5li2jcf1 m7rPMZcwZOS3To8bk3OBaMGhVEc1F8GtJBbc1rn/HCL

  • 微信小程序实现瀑布流布局与无限加载的方法详解

    前言 瀑布流布局是一种比较流行的页面布局方式,最典型的就是Pinterest.com,每个卡片的高度不都一样,形成一种参差不齐的美感. 在HTML5中,我们可以找到很多基于jQuery之类实现的瀑布流布局插件,轻松做出这样的布局形式.在微信小程序中,我们也可以做出这样的效果,不过由于小程序框架的一些特性,在实现思路上还是有一些差别的. 今天我们就来看一下如何在小程序中去实现这种瀑布流布局: 小程序瀑布流布局 我们要实现的是一个固定2列的布局,然后将图片数据动态加载进这两列中(而加载进来的图片,会

  • 微信小程序实现瀑布流分页滚动加载

    本文实例为大家分享了微信小程序实现瀑布流分页滚动加载的具体代码,供大家参考,具体内容如下 两种分页方式 普通的分页效果会在页面底部提供点击下一页和上一页的按钮,在点击了按钮之后才会触发调取数据的接口,这种方式的用户体验一般 另一种分页效果不需要用户点击按钮,只要浏览到当前页面的后几条数据时,系统会自动发送请求获取后一页的数据,并展示到页面上,这样就可以实现类似无限滚动的效果 以csdn为例,当滚动条到达这个地方时,会自动调用请求下一页数据的接口,然后累加到加载完成的数据列表中 实现思路 滚动分页

  • 微信小程序dom操作的替代思路实例分析

    本文实例讲述了微信小程序dom操作的替代思路.分享给大家供大家参考,具体如下: 微信小程序无法操作dom,这意味着之前js中的各种习惯方法必须换一种思路实现 在尝试了几类情况后,发现部分情况下可以用{{}}变量绑定来实现效果. 比如: 一.实现view的显示和隐藏 在js中的data设置变量 bottomHidden1:"block": 然后在wxml中的view中设置<view class="bottom1" style="display:{{bo

  • 小程序实现瀑布流动态加载列表

    本文实例为大家分享了小程序实现瀑布流动态加载列表的具体代码,供大家参考,具体内容如下 最近业务需要做一个商城列表,就自己写了一个瀑布流来加载列表. 这个列表在很多地方都需要用到,就给写成组件,方便使用. 1.goodsBox.js代码 想法很简单,就是判断两列的高度,将数据插入低的一列. let leftHeight = 0,   rightHeight = 0; //分别定义左右两边的高度 let query; Component({   /**    * 组件的属性列表    */   pr

  • uni-app小程序中父组件和子组件传值的实现实例

    目录 前言 一.父组件向子组件传值 二.子组件向父组件传值 总结 前言 1.父组件向子组件传值 → 通过数据绑定 2.子组件向父组件传值 → 通过事件 一.父组件向子组件传值 通过props实现,即:子组件通过props来接收父组件传过来的值 实现 父组件中: 1.引入子组件 2.注册子组件 3.通过标签形式载入:使用数据绑定进行传值 子组件中: 1.通过props接收父组件中传递过来的值 具体演示代码 父组件:index.vue <template> <comA :list="

  • uniapp小程序视图容器cover-view使用详解

    目录 一,cover-view 1.1 基础知识 1.2 各平台差异 1.3 不支持的CSS 附:uni-app中cover-view覆盖原生组件 总结 一,cover-view 首先我们需要知道,cover-view是可以覆盖在原生组件上的文本视图,也就是cover-view组件的层级高于原生组件,就像是原生组件的层级高于前端组件一样,如flash层级就高于div的层级. 部分组件,比如map.video.textarea.canvas是通过原生组件实现的,原生组件无法被前端组件覆盖,程序员需

  • uniapp小程序配置tabbar底部导航栏实战指南

    目录 前言: 正文 Tips 1.首先我们准备好自己项目所需要的tab图标 2.找到我们的pages.json文件进行配置 3.配置一下导航栏标题内容 4.来看看我们的成果(效果图) 总结 前言: 配置底部导航栏首先需要大家准备好自己想要使用的图标,每个tab可以选择两个图标,分别为选中前的和选中后的.之后我们根据uniapp官网提供的 uniapp官网tabbar配置项,话不多说直接上正文一起来学习一下如何配置底部导航栏吧. 正文 首先我们先看一下官网中的介绍:如果应用是一个多 tab 应用,

  • uni-app小程序沉浸式导航实现的全过程

    目录 1. 开始 2. page的样式 3. onPageScroll 4. 性能问题 5. 方案 6. 代码 7. 注意事项 总结 1. 开始 项目要在多个页面上加自定义导航栏,还要有渐变效果,就是随着页面上滑,导航栏透明度由0逐渐变为1.这里面有几个基本点需要注意下. 2. page的样式 page 不能是height: 100%,可以设置height: auto,这样才可以触发 onPageScroll. 3. onPageScroll 只有 page 才有 onPageScroll 事件

随机推荐