微信小程序实现瀑布流布局

实现的效果图如下显示:

一,需求分析

  • 布局分为两列,两列的高度随着图片的插入而改变
  • 默认给左右两列插入一张图片,插入图片后,根据两列的的高度做为判断依据,依次给高度更低的一列插入图片

二,使用Component实现瀑布流,复用性更强。

通过Component把瀑布流封装成一个组件,可以再其他需要瀑布流的页面调用,减少了代码量,规范代码,更方便,效率更高。

1,首先自定义瀑布流组件

在需要瀑布流页面的json文件引入组件


使用瀑布流组件

2,设置组件wxml布局

<view class="waterfall clear"><view class="leftfall left" id="leftfall"><view class="img-item" wx:for="{{ leftfall }}" wx:key="this"><image src="{{ item.photo_url }}" lazy-load="{{ true }}" mode="widthFix" bindload="waterfall"></image></view><text class='recom'>珍藏已久的vsco调色合集,最美素颜。</text><view class="info clear"><image class='handimg' mode="widthFix"></image><text class='dollar'>¥ 233.5</text></view>  </view><view class="rightfall right" id="rightfall"><view class="img-item" wx:for="{{ rightfall }}" wx:key="this"><image src="{{ item.photo_url }}" lazy-load="{{ true }}" mode="widthFix" bindload="waterfall"></image></view><text class='recom'>珍藏已久的vsco调色合集,最美素颜。</text><view class="info clear"><image class='handimg' mode="widthFix"></image><text class='dollar'>¥ 233.5</text></view> </view>
</view>

image组件的mode设置为widthFix为了让图片适应容器的宽度并且等比例缩放

3,设置wxss样式如下

page{background: #f5f5f5;
}
.maincont{width: 100%;background: #ffffff;
}
.waterfall{padding:30rpx;background: #f5f5f5;
}
.leftfall,.rightfall,.imgbox{width: 340rpx;height: auto;
}
.img-item{margin: 0 0 30rpx 0;border-radius: 15rpx;overflow: hidden;box-shadow: 2rpx 2rpx 10rpx #c0c0c0;
}
.recom{width: 90%;height: 90rpx;margin: 0 5% 0 5%;line-height: 30rpx;font-size: 28rpx;float: left;font-weight: bold;overflow: hidden;display: -webkit-box;-webkit-line-clamp: 3;-webkit-box-orient: vertical;
}
.handimg{width: 50rpx;height: 50rpx;float: right;display: inline-block;border-radius: 50%;background: skyblue;
}
.dollar{height: 50rpx;line-height: 50rpx;margin: 0 10rpx 0 0;display: inline-block;float: left;font-size: 24rpx;font-weight: bold;color: red;
}
.info{width: 90%;height: 50rpx;margin:25rpx 5% 15rpx 5%;float: left;
}.clear::after{content: '';clear: both;height: 0;display: block;visibility: hidden;
}

根据以上代码,可以看出在主页面获取的数据dataFall通过组件传值的方式,传送到子组件,然后再将数据放进leftfall和rightfall这两个数组里面

具体的参数说明

参数说明:
dataFall为从父组件获取到的瀑布流数据,当dataFall的数据出现改变时候,在observer:function(){}的异步操作中把数据赋值给imglist

properties: {dataFall: {type: Array,// value: [],observer: function (newVal, oldVal) {this.setData({imgList: newVal})if (this.data.imgList.length !== 0) {setTimeout(function () {// 数据改变以后首次执行瀑布流代码that.waterfall()// 更改加载瀑布流的状态that.setData({fallStatus: false})}, 0)}}},},/*** 组件的初始数据*/data: {imgList: [],          //  从父组件获取到的瀑布流总数据fallStatus: false,    //  瀑布流加载的状态leftfall: [],         //  瀑布流左列容器的数据组rightfall: [],        //  瀑布流右列容器的数据组},

具体的逻辑实现

一开始我们定义两个变量来记录leftfall和rightfall这两列装载图片容器的高度,通过小程序内置Api接口wx.createSelectorQuery()来获取两列容器的高度,一开始两列容器的高度都为0的时候,默认给左边第一列容器插入一张图片,后续进行对比当leftfall的高度大于rightfall的高度时候将数据插入rightfall 数组 反之将数据插入leftfall数组。

具体实现步骤

1,获取两列容器的高度

自定义变量leftfall和rightfall,通过微信内置Api接口wx.createSelectorQuery().selectAll(’#leftfall,#rightfall’).boundingClientRect(function (res) {}).exec();来获取两列容器的高度。

需要注意的地方:在自定义组件内wx.createSelectorQuery()存在一个指向性问题所以在后面需要加上in(this)重新指向自定义组件才可以获取组件内的元素的高度属性。

   let left_hei = ''let right_hei = ''let that = thisconst query = wx.createSelectorQuery().in(this);query.selectAll('#leftfall,#rightfall').boundingClientRect(function (res) {left_hei = res[0].height        // 获取左列容器的高度right_hei = res[1].height      // 获取右列容器的高度}).exec();

2,对比两列容器的高度判断数据插入那个数组

(1)为了防止有些图片在同步加载的过程中图片过大加载过慢而导致瀑布流图片墙分布的不规则,所以我们把判断两列高度的代码先封装成一个inserImg方法,

      function inserImg() {if (that.data.imgList.length != 0) {if (left_hei === right_hei) {that.data.leftfall.push(that.data.imgList[0])that.setData({leftfall: that.data.leftfall})} else if (left_hei > right_hei) {that.data.rightfall.push(that.data.imgList[0])that.setData({rightfall: that.data.rightfall})} else if (left_hei < right_hei) {that.data.leftfall.push(that.data.imgList[0])that.setData({leftfall: that.data.leftfall})  }// 插入数据后,从总数据里删除已插入的数据that.setData({imgList: that.data.imgList.slice(1)})}}

(2)在执行完wx.createSelectorQuery()获取到leftfall和rightfall后的异步操作里面再去执行inserImg方法去做两列容器的高度判断,在把数据插入到那一列中。

   let left_hei = ''let right_hei = ''let that = thisconst query = wx.createSelectorQuery().in(this);query.selectAll('#leftfall,#rightfall').boundingClientRect(function (res) {left_hei = res[0].height        // 获取左列容器的高度right_hei = res[1].height      // 获取右列容器的高度//  获取完两列容器的高度后判断数据插入那一列数组inserImg();}).exec();

3,分配所有数据

因为每一次任意一列插入一张图片的时候都需要重新获取leftfall和rightfall这两容器的高度作比较,所以我们把全部的瀑布流代码封装一个waterfall的方法,然后使用image组件里的bindload方法在插入一张图片等图片加载完后自动执行一次waterfall方法,直到把imglist里的所有数据都分配到leftfall和rightfall。

image组件代码

<image src="{{ item.photo_url }}" lazy-load="{{ true }}" mode="widthFix" bindload="waterfall"></image>
     waterfall(event) {let left_hei = ''let right_hei = ''let that = thisconst query = wx.createSelectorQuery().in(this);query.selectAll('#leftfall,#rightfall').boundingClientRect(function (res) {left_hei = res[0].height        // 获取左列容器的高度right_hei = res[1].height      // 获取右列容器的高度// 获取左右两列容器高度后对比两边容器高度插入数据inserImg();}).exec();function inserImg() {if (that.data.imgList.length != 0) {if (left_hei === right_hei) {that.data.leftfall.push(that.data.imgList[0])that.setData({leftfall: that.data.leftfall})} else if (left_hei > right_hei) {that.data.rightfall.push(that.data.imgList[0])that.setData({rightfall: that.data.rightfall})} else if (left_hei < right_hei) {that.data.leftfall.push(that.data.imgList[0])that.setData({leftfall: that.data.leftfall})  }// 插入数据后,从总数据里删除已插入的数据that.setData({imgList: that.data.imgList.slice(1)})} else {// 瀑布流加载结束向父组件传递信息,可进行上拉加载操作,获取分页数据that.triggerEvent('waterFallResh', { loading: true })that.setData({fallStatus: true})}}}

整合完整的瀑布流js代码

具体代码如下:

Component({/*** 组件的属性列表*/options: {addGlobalClass: true},properties: {dataFall: {type: Array,// value: [],observer: function (newVal, oldVal) {this.setData({imgList: newVal})if (this.data.imgList.length !== 0) {setTimeout(function () {// 数据改变以后首次执行瀑布流代码that.waterfall()// 更改加载瀑布流的状态that.setData({fallStatus: false})}, 0)}}},},/*** 组件的初始数据*/data: {imgList: [],          //  从父组件获取到的瀑布流总数据fallStatus: false,    //  瀑布流加载的状态leftfall: [],         //  瀑布流左列容器的数据组rightfall: [],        //  瀑布流右列容器的数据组},methods: {// 瀑布流代码waterfall(event) {let left_hei = ''let right_hei = ''let that = thisconst query = wx.createSelectorQuery().in(this);query.selectAll('#leftfall,#rightfall').boundingClientRect(function (res) {left_hei = res[0].height        // 获取左列容器的高度right_hei = res[1].height      // 获取右列容器的高度// 获取左右两列容器高度后对比两边容器高度插入数据inserImg();}).exec();function inserImg() {if (that.data.imgList.length != 0) {if (left_hei === right_hei) {that.data.leftfall.push(that.data.imgList[0])that.setData({leftfall: that.data.leftfall})} else if (left_hei > right_hei) {that.data.rightfall.push(that.data.imgList[0])that.setData({rightfall: that.data.rightfall})} else if (left_hei < right_hei) {that.data.leftfall.push(that.data.imgList[0])that.setData({leftfall: that.data.leftfall})  }// 插入数据后,从总数据里删除已插入的数据that.setData({imgList: that.data.imgList.slice(1)})} else {// 瀑布流加载结束向父组件传递信息,可进行上拉加载操作,获取分页数据that.triggerEvent('waterFallResh', { loading: true })that.setData({fallStatus: true})}}},}
})

点击查看瀑布流布局使用插槽自定义图片内容

微信小程序实现瀑布流布局相关推荐

  1. 微信小程序双瀑布流布局+动态懒加载

    效果图 实现代码: 思路: 将双瀑布流分为left.right两个数据流,通过动态获取两边数据的动态高度来进行判断,下一条数据插入低的一方. 因为用户所上传图片高度不一致,所以image的mode属性 ...

  2. 小程序实现瀑布流布局

    ** 小程序实现瀑布流 ** 实现效果如图:一:需求分析 页面主要分成两列,每个条目的高度不固定,条目主要由封面图+标题+头像+发布者昵称组成多列排列要求,第一条在左侧,第二条在右侧,后续的根据左右两 ...

  3. 微信小程序实现瀑布流(FlowLayout)效果

    前言:小程序不同于安卓直接提供布局的配置,而必须要像写前端页面一样来写.并且小程序没有像web网页的DOM和BOM操作,准确的来说是存在这么个API的,但是我测试使用的时候,得到的数据总是不尽人意,地 ...

  4. 关于微信小程序简单瀑布流的制作

    应业务需要,制作了简单的瀑布流,应用于购物平台. 首先是单个内容组件.考虑到后台计算的消耗,因而将内容里的图片高度采用直接输入.到时传入数据时需注意. <!--components/showit ...

  5. 微信小程序实现瀑布流实例

    瀑布流的效果图如下: 1.wxml中的代码如下 <!--pages/lsittest/listtest.wxml--> <view class="containers&qu ...

  6. 微信小程序实现瀑布流 仿小红书

    要做的小红书瀑布流效果 homepage.wxml代码 <!-- 瀑布流大概的思路就是,直接定义两列等宽的view,然后两列都加载相同的数据wx:if="{{index%2==1}}& ...

  7. 微信小程序实现瀑布流,如何实现!

    废话不多,不爱表达,直接上代码! 首先,瀑布流样式都知道左右高度是不一样的,所以需要我们写两套样式,左边和右边. <view class='left'><block wx:for=& ...

  8. uview 瀑布流_最简单的微信小程序瀑布流布局方法

    最近写一个小程序的瀑布流布局,发现网上别人写的都是css加js的方法,页面分两列,加载数据通过JS分别载入到两列中.比较复杂,研究了一下,弄了一个比较简单的方法,分享给大家. 效果如下图: 小程序瀑布 ...

  9. 微信小程序中实现瀑布流布局和无限加载

    瀑布流布局是一种比较流行的页面布局方式,最典型的就是Pinterest.com,每个卡片的高度不都一样,形成一种参差不齐的美感. 在HTML5中,我们可以找到很多基于jQuery之类实现的瀑布流布局插 ...

最新文章

  1. oracle 12c 13姨
  2. Anaconda 环境下 对Tushare进行测试
  3. NET 2.0中WinForm自定义的程序配置存放到哪里去了
  4. wcf 远程终结点已终止该序列 可靠会话出错
  5. Hive集成Tez引擎跑任务出现的问题(Java heap space问题)
  6. 如何在WebLogic Server中创建MySQL数据源
  7. IntelliJ IDEA 如何设置编辑窗口的背景图片
  8. 昆虫繁殖(信息学奥赛一本通-T1312)
  9. java 两层while_java – while while循环满足2个条件之一
  10. 阿里云实现人脸登录(人脸库 OSS)
  11. 深度学习简明教程系列 —— 经典模型(合集)
  12. JavaScript基础知识总结(6张思维导图)
  13. 怎么将两个PDF合并成一个?这里有三个小妙招分享给你
  14. 动态MAC地址和静态MAC地址
  15. 华为项目管理金种子培训教材(资料下载)
  16. python如何下载安装spacy_Python spaCy
  17. TWaver GIS制作穹顶之下的雾霾地图
  18. t430服务器安装系统,Dell PowerEdge T430
  19. 便宜实惠的移动自动快充:50元仅需48.90元
  20. PEI表面修饰CNTs步骤及原理

热门文章

  1. python求均方根,python中函数的均方根
  2. Java工程师修炼之道! | 送10本书籍
  3. c语言学的是什么,C语言怎么学?
  4. CSS3实现实时时间数字滚动
  5. MyISAM 存储引擎(mysql 8.0)
  6. JAVA代理模式与动态代理模式
  7. 开源机器学习模型管理工具DVC介绍
  8. Python Django,模型,模型管理器类(models.Manager)(与数据库交互的接口),自定义模型管理器类
  9. 供应链金融服务平台系统开发-成熟、稳定、节本、增效,一站式信息交易管理平台
  10. 数据结构之链表(LinkedList详解)