瀑布流结构是现在很普遍的结构形式,,那么小程序瀑布流要怎样实现解决,,网上能搜到的小程序瀑布流解决方案,,要么代码重大、逻辑杂乱,,要么实现不了营业功效,,以是把我在项目中的实现方案给各人分享下。。。。

最简朴的实现方案,,不适用有分页的场景。。。。
这个方案简朴的原因是由于仅仅使用了css的属性。。。。
使用column-count 属性可以指定页面显示的列数,,一般瀑布流都是2列,,以是可以界说class
.list-masonry {
column-count: 2; //2列
column-gap: 20rpx; //列间距
}
界面界说也很简朴
<view class='list-masonry'>
<block wx:for="{{goodsList}}" wx:key="{{item.id}}">
<template is='goodsCard' data="{{data:item}}" />
</block>
</view>
其中,,goodsList为页面展示的数据,,goodsCard为瀑布流的卡片,,这个很容易明确。。。。
注重,,瀑布流的卡片需要css属性 display: inline-block; 将卡片设置为 内联元素。。。。image 组件设置缩放模式 mode="widthFix" 来坚持图片宽高比。。。。
column-count 属性默认是以列的形式来填充数据的。。。。好比我们有20条数据,,1 ~ 10 条数据会展示在左边第一列,,11 ~ 20 条数据会展示在第二列。。。。
若是有分页,,再往数组中增添20条数据后,,就会酿成 1 ~ 20 条数据会在左边,,21 ~ 40 条数据会展示在右边。。。。用户体验很是差。。。。
由于 column-fill: balance; 填充属性无效,,无法指定填充顺序为行的形式。。。。
以是这种实现方案只能一下加载完所有数据,,不适用于分页。。。。
Component实现瀑布流,,功效强盛,,滑动流通
通过自界说组件,,用自己的思绪实现瀑布流。。。。然后在需要瀑布流的地方直接挪用,,利便复用。。。。
没有Demo!! 随着我的方法一步一步来,,就能轻松实现。。。。
建议在项目根目录建设文件夹component,,然后在该目录下建设文件夹WaterFallView,,最后在WaterFallView下建设component。。。。(鼠标右键->新建->Component)。。。。
2. 设计瀑布流的wxml。。。。
瀑布流的结构简朴,,只有左右2列。。。。以是在设计UI的时间,,结构很简朴。。。。
<view class='fall-container'>
<!-- 左边一列 -->
<view class='fall-left'>
<block wx:for="{{leftList}}" wx:key="{{item.id}}">
<!--瀑布流内容卡片-->
<template is='goodsCard' data="{{data:item}}" />
</block>
</view>
<!--右边一列 -->
<view class='fall-right'>
<block wx:for="{{rightList}}" wx:key="{{item.id}}">
<!--瀑布流内容卡片-->
<template is='goodsCard' data="{{data:item}}" />
</block>
</view>
</view>
左右双方,,一边一个View。。。。通过这两个View 来展示瀑布流的两列。。。。每个View对应一个数据源,,由此可见,,这套思绪的重点是这个两个数据源的处理。。。。每个View中的template 为瀑布流中的卡片,,就不介绍了。。。。
凌驾两列的瀑布流较量少见,,本篇不思量,,但可用本篇的思绪来实现。。。。
.fall-container {
width: 100%;
display: flex;
}
.fall-left {
display: flex;
flex-direction: column;
}
.fall-right {
display: flex;
flex-direction: column;
margin-left: 20rpx;
}
凭证上面的 wxml 结构,,这个组件的焦点逻辑就是怎样把要展示的数据item 放入leftList、rightList这两个数组中。。。。
怎样分配数据item???这个简朴,,我们可以界说2个变量 leftHight、rightHight,,来划分纪录leftList、rightList数组中图片的高度(可以明确为左边View、右边View的高度,,着实只是图片的高度,,但已知足瀑布流的的需求)。。。。当leftHight 大于 rightHight时,,把数据放入rightList,,并让rightHight叠加数据中图片的高度。。。。当rightHight大于 leftHight 时,,把数据放入leftList,,并让leftHight 叠加数据中图片的高度。。。。
if (leftHight == rightHight) { //第1个item放左边
leftList.push(tmp);
leftHight = leftHight + tmp.itemHeight;
} else if (leftHight < rightHight) {
leftList.push(tmp);
leftHight = leftHight + tmp.itemHeight;
} else {
rightList.push(tmp);
rightHight = rightHight + tmp.itemHeight;
}
瀑布流展示图片的时间,,需要知道图片的宽高,,然后凭证图片的宽高比来设置 image组件的宽高。。。。以是若是你们的数据没有宽高或宽高比,,很难实现瀑布流。。。。虽然可以通过代码获得图片宽高,,但会对性能以及用户体验有很大影响,,不推荐这么做。。。???梢院秃筇ㄍ馓教窒,,看怎样加上宽高数据。。。。
Component有自己生命周期要领,,甚至可以象Page一样,,当做一个单独的页面使用。。。???梢栽谒纳芷谝熘谢窕竦闷俨剂鞯目矶,,以及图片的最大高度。。。。
attached: function () { //第一个生命周期要领
wx.getSystemInfo({
success: (res) => {
let percentage = 750 / res.windowWidth; //750rpx/屏幕宽度
let margin = 20 / percentage; //盘算瀑布流间距
itemWidth = (res.windowWidth - margin) / 2; //盘算 瀑布流展示的宽度
maxHeight = itemWidth / 0.8 //盘算瀑布流的最大高度,,防止长图霸屏
}
});
},
拿到瀑布流的宽度后,,就可以凭证图片的宽高比,,盘算出 image 组件的宽高。。。。
let tmp = listData[i]; //单条数据
tmp.width = parseInt(tmp.width); //图片宽度
tmp.height = parseInt(tmp.height); //图片高度
tmp.itemWidth = itemWidth //image 宽度
let per = tmp.width / tmp.itemWidth; //图片宽高比
tmp.itemHeight = tmp.height / per; //image 高度
if (tmp.itemHeight > maxHeight) {
tmp.itemHeight = maxHeight; //image 高度,,不凌驾最大高度
}
在template中,,image的宽高需要声明下。。。。单位是px,不是rpx
<image
class='card-img'
mode='aspectFill'
style='width:{{data.itemWidth}}px;height:{{data.itemHeight}}px;'
src='{{data.img}}'
lazy-load>
</image>
/**
* 瀑布流组件
*/
var leftList = new Array();//左侧荟萃
var rightList = new Array();//右侧荟萃
var leftHight = 0, rightHight = 0, itemWidth = 0, maxHeight = 0;
Component({
properties: {},
data: {
leftList: [],//左侧荟萃
rightList: [],//右侧荟萃
},
attached: function () {
wx.getSystemInfo({
success: (res) => {
let percentage = 750 / res.windowWidth;
let margin = 20 / percentage;
itemWidth = (res.windowWidth - margin) / 2;
maxHeight = itemWidth / 0.8
}
});
},
methods: {
/**
* 填充数据
*/
fillData: function (isPull, listData) {
if (isPull) { //是否下拉刷新,,是的话扫除之前的数据
leftList.length = 0;
rightList.length = 0;
leftHight = 0;
rightHight = 0;
}
for (let i = 0, len = listData.length; i < len; i++) {
let tmp = listData[i];
tmp.width = parseInt(tmp.width);
tmp.height = parseInt(tmp.height);
tmp.itemWidth = itemWidth
let per = tmp.width / tmp.itemWidth;
tmp.itemHeight = tmp.height / per;
if (tmp.itemHeight > maxHeight) {
tmp.itemHeight = maxHeight;
}
if (leftHight == rightHight) {
leftList.push(tmp);
leftHight = leftHight + tmp.itemHeight;
} else if (leftHight < rightHight) {
leftList.push(tmp);
leftHight = leftHight + tmp.itemHeight;
} else {
rightList.push(tmp);
rightHight = rightHight + tmp.itemHeight;
}
}
this.setData({
leftList: leftList,
rightList: rightList,
});
},
}
})
a. 注册自界说组件
在使用自界说组件的Page的json文件中声明要使用的组件
{
....
"usingComponents": {
"waterFallView": "../../component/WaterFallView/WaterFallView"
}
}
b. 在 wxml 中添加组件,,并加上 id
<waterFallView id='waterFallView'>
</waterFallView>
c. 在JS中找到组件,,并挪用fillData() 要领。。。。下拉刷新时 isFull 传 true。。。。
fillData: function (isFull,goods){
let view = this.selectComponent('#waterFallView');
view.fillData(isFull, goods);
},
KESION pp电子软件
KESION pp电子软件是海内领先的在线教育软件及私域社交电商软件服务提供商,,恒久专注于为企业提供在线教育软件及社交电商SaaS平台解决方案。。。。
公司焦点产品云开店SaaS社交电商服务平台、在线教育SaaS服务平台、教育企业数字化SaaS云平台、企微营销助手、私有化自力安排品牌网校和在线教育咨询等。。。。KESION 一直通过手艺立异,,提供产品和服务,,助力企业向数字化转型,,通过科技驱动商业刷新,,让商业变得更智慧!
pp电子最新新闻,,微信已经开通了搜一搜功效,,直接实现在微信直达搜索功效,,那么在设置小程序页面问题时要怎样设置才有搜索?...
列表上拉下拉加载数据是再常见不过的功效,,第一个想到的是scroll-view组件,,内里有两个事务,,划分是bindscrolltoupper(拉到最顶部)和bindscrolltolower(拉到最底部