小程序瀑布流布局

实现方案
左右两边是两列,两个数组,用boundingClientRect获取左右的高度,判断下一个应该添加到哪个数组,接口用的豆瓣公共的接口,用scroll-view实现下拉刷新上拉加载更多
wxml片段:
1 <block wx:if="{{!isNoData}}"> 2 <view class="pro-box"> 3 <view 4 id="leftList" 5 class="pro-list pro-list1"> 6 <view 7 wx:for="{{leftList}}" 8 wx:key="id" 9 class="pro-item"> 10 <image class="img" mode="widthFix" src="{{item.pic}}"></image> 11 <view class="title">{{item.title}}</view> 12 <view class="ft"> 13 <view class="price"> 14 <text class="pre">¥</text>{{item.minPric}} 15 </view> 16 <view class="num">{{item.minNum}}{{item.unit}}起批</view> 17 </view> 18 </view> 19 </view> 20 <view 21 id="rightList" 22 class="pro-list pro-list2"> 23 <view 24 wx:for="{{rightList}}" 25 wx:key="id" 26 class="pro-item"> 27 <image class="img" mode="widthFix" src="{{item.pic}}"></image> 28 <view class="title">{{item.title}}</view> 29 <view class="ft"> 30 <view class="price"> 31 <text>¥</text>{{item.minPric}} 32 </view> 33 <view class="num">{{item.minNum}}件起批</view> 34 </view> 35 </view> 36 </view> 37 </view> 38 <mp-loading wx:if="{{isLoading}}" ext-class="loading" type="circle"></mp-loading> 39 <view wx:if="{{isComplete}}" class="no-more">没有更多数据了</view> 40 </block> 41 <view wx:else class="no-data">暂无<text class="keyword">{{formData.keyWord}}</text>数据~</view>
js代码片段:
1 import { get } from '../../../../api/http.js' 2 import { showFail } from '../../../../utils/public.js' 3 const app = getApp() 4 let leftHeight = 0 5 let rightHeight = 0 6 Page({ 7 8 /** 9 * 页面的初始数据 10 */ 11 data: { 12 isLoading: false, // 列表是否正在加载更多 13 isComplete: false, // 列表是否所有数据都加载完成 14 isNoData: false, // 列表是否没有数据 15 curPage: 1, // 列表当前页 16 pageSize: 20, // 列表每页显示多少条 17 leftList: [], 18 rightList: [] 19 }, 20 21 // 获取列表 22 getList () { 23 const that = this 24 const curPage = that.data.curPage 25 const pageSize = that.data.pageSize 26 const keyWord = '' 27 let isShowLoading = true 28 29 // 第一页的loading采用http封装里面的loading,其他采用本页中的isLoading 30 if (curPage !== 1) { 31 isShowLoading = false 32 that.setData({ 33 isLoading: true 34 }) 35 } 36 37 get('/api/shop/queryListCompany', { 38 data: { 39 page: curPage, 40 pageSize, 41 keyword: keyWord 42 }, 43 isShowLoading: isShowLoading 44 }).then(async (res)=> { 45 // 请求完成后隐藏loading 46 that.setData({ 47 isLoading: false 48 }) 49 if (res.code === '1') { 50 const result = res.data 51 const dataArry = result.data || [] 52 const totalPage = result.totalPage 53 const total = result.totalCount 54 const leftList = that.data.leftList 55 const rightList = that.data.rightList 56 57 // 当返回总条数为0时说明没有数据 58 if (total === 0) { 59 that.setData({ 60 isNoData: true 61 }) 62 return 63 } 64 65 if (curPage > totalPage) { 66 that.setData({ 67 isComplete: true 68 }) 69 return 70 } 71 72 for (const item of dataArry.values()) { 73 const itemObj = { 74 id: item.id, 75 pic: app.globalData.fileUrl + item.authPic, 76 title: item.companyName, 77 minPric: '35.00', 78 minNum: 99, 79 unit: '件' 80 } 81 if (leftHeight <= rightHeight) { 82 leftList.push(itemObj) 83 } else { 84 rightList.push(itemObj) 85 } 86 await that.getBoxHeight(leftList, rightList) 87 } 88 // 请求完成后隐藏loading 89 that.setData({ 90 curPage: curPage + 1 91 }) 92 } else { 93 showFail(res.msg) 94 } 95 }).catch((error) => { 96 // 请求完成后隐藏loading 97 that.setData({ 98 isLoading: false 99 }) 100 showFail() 101 }) 102 }, 103 104 //获取左右两边高度 105 getBoxHeight (leftList, rightList) { 106 const that = this 107 return new Promise((resolve) => { 108 that.setData({ 109 leftList, 110 rightList 111 }, () => { 112 let query = wx.createSelectorQuery().in(that) 113 query.select('#leftList').boundingClientRect() 114 query.select('#rightList').boundingClientRect() 115 query.exec((res) => { 116 if (res[0]) { 117 leftHeight = res[0].height 118 rightHeight = res[1].height 119 } 120 resolve() 121 }) 122 }) 123 }) 124 }, 125 126 /** 127 * 生命周期函数--监听页面加载 128 */ 129 onLoad: function (options) { 130 this.getList() 131 }, 132 133 /** 134 * 生命周期函数--监听页面初次渲染完成 135 */ 136 onReady: function () { 137 138 }, 139 140 /** 141 * 生命周期函数--监听页面显示 142 */ 143 onShow: function () { 144 145 }, 146 147 /** 148 * 生命周期函数--监听页面隐藏 149 */ 150 onHide: function () { 151 152 }, 153 154 /** 155 * 生命周期函数--监听页面卸载 156 */ 157 onUnload: function () { 158 159 }, 160 161 /** 162 * 页面相关事件处理函数--监听用户下拉动作 163 */ 164 onPullDownRefresh: function () { 165 166 }, 167 168 /** 169 * 页面上拉触底事件的处理函数 170 */ 171 onReachBottom: function () { 172 const that = this 173 if (that.data.isLoading || that.data.isComplete || that.data.isNoData) { 174 return 175 } 176 that.getList() 177 }, 178 179 /** 180 * 用户点击右上角分享 181 */ 182 onShareAppMessage: function () { 183 184 } 185 })
wxss文件:
1 .pro-box{width: 690rpx;margin: 0 auto;padding-top: 75rpx;overflow: hidden;} 2 .pro-list,.pro-item .img{width: 335rpx;overflow: hidden;} 3 .pro-list1{float: left;} 4 .pro-list2{float: right;} 5 .pro-item{margin-top: 30rpx;} 6 .pro-item .img{border-radius: 16rpx;} 7 .pro-item .title{color: #333;font-size: 30rpx;font-weight: bold;line-height: 42rpx;margin-left: 10rpx;margin-right: 10rpx;} 8 .pro-item .ft{display: flex;align-items: center;} 9 .pro-item .price{color: #E94F5A;font-size: 36rpx;font-weight: bold;margin-right: 30rpx;} 10 .pro-item .price .pre{font-size: 24rpx;position: relative;top: -2rpx;} 11 .pro-item .num{color: #999;font-size: 26rpx;} 12 13 .loading .weui-loadmore,.no-more{margin-bottom:0;margin-top: 20rpx;padding-bottom: 20rpx;} 14 .loading .weui-loadmore__tips,.no-more{font-size: 30rpx;color: #aaa;text-align: center;} 15 .no-data{text-align: center;color: #aaa;padding:50rpx;font-size: 30rpx;} 16 .no-data .keyword{color: #E94F5A;}
参考文献:

浙公网安备 33010602011771号