思路:
- 布局按照纵向分布, 以列为单位;
- 元素单个儿分配, 每个元素寻找最短的一列;
- 填充;
- 组件内容循环, 单个儿item设置为抽象节点.
目前情况我很抱歉😂渲染一屏完全没有问题, 可是在进行到上滑加载时, 第一屏到第二屏会稍微卡顿一下, 规律还没观察出来所以没有解决这个问题....
组件代码
wxml
<scroll-view class="flow-scroll" scroll-y enhanced show-scrollbar="{{false}}" bindscrolltolower="toBottom">
<view class="flow-container">
<!-- 按列循环先 -->
<view wx:if="{{list.length > 0}}" wx:for="{{cols}}" wx:key="index" wx:for-item="col" class="flow-col" style="margin-right: {{index !== cols.length - 1 ? seam : 0}};">
<!-- 每列数据: 这里用到了抽象节点 -->
<item wx:for="{{col}}" wx:key="id" wx:for-index="idx" item="{{item}}"></item>
</view>
</view>
</scroll-view>
wxss
.flow-scroll {
width: 100%;
height: 100%;
}
.flow-container {
display: flex;
justify-content: space-between;
align-items: flex-start;
}
.flow-col{
width: 1rem;
flex: 1 1 auto;
}
.image {
width: 100%;
}
js
Component({
properties: {
// 必传参: 列表数据
list: {
required: true,
type: Array,
value: []
},
// 列数
colNum: {
type: Number,
value: 2
},
// 列中间的缝隙
seam: {
type: String,
value: "16rpx"
},
},
data: {
cols: [],
},
methods: {
initCols() {
let {
colNum
} = this.data;
// 获取到页面需要几列时, 对列进行设置
// 主要内容为: 将每个列设置为数组
let cols = new Array(colNum);
for (let i = 0; i < cols.length; i++) {
cols[i] = [];
}
this.setData({
cols
})
},
async renderPage() {
for (let item of this.data.list) {
// 涉及到小程序获取没列的高度需要一定的时间, 一个设置完才能设置接下来的一个, 所以得同步
let {
minColIndex,
currentColIndex
} = await this.renderItem();
this.setData({
[`cols[${minColIndex}][${currentColIndex}]`]: item
})
}
},
renderItem() {
return new Promise(resolve => {
this.witchColumn().then(minColIndex => {
let currentColIndex = this.data.cols[minColIndex].length;
resolve({
minColIndex,
currentColIndex
})
});
})
},
witchColumn() {
return new Promise((resolve => {
const query = wx.createSelectorQuery().in(this);
query.selectAll('.flow-col').boundingClientRect().exec(arr => {
// colsHeightGroup ⬇️
const colsHeightArr = arr[0].map(col => col.height);
let minHeightIndex = colsHeightArr.indexOf(Math.min.apply(Math, colsHeightArr));
resolve(minHeightIndex);
});
}))
},
toBottom() {
this.triggerEvent('getMoreData');
},
},
lifetimes: {
attached() {
// 进入组件就先对列进行设置
this.initCols();
}
},
observers: {
list(list) {
if (list.length > 0) {
// 在数据发生变化并且有真实数据时渲染页面
this.renderPage();
}
}
}
})
json: 目前微信小程序没法像VUE那样子传递循环出的参数并且设置针对单值的插槽儿, 可用的类似方法暂时只能是设置抽象节点.
{
"component": true,
"componentGenerics": {
"item": true
}
}
以下是列表每一项
emmm我是这么理解的, 就是一个组件中.....又套了一个组件哈哈哈哈哈哈方便传每一项的值, 弥补了小程序不能创建循环中的插槽. 不过它真正的作用![](https://img.haomeiwen.com/i25174645/d8bcf8fa1a62b682.png)
https://developers.weixin.qq.com/miniprogram/dev/framework/custom-component/generics.html
wxml
<view class="flow-item">
<image src="{{item.url}}" mode="widthFix" class="image"></image>
<view class="introduce">{{item.content}}</view>
</view>
js
Component({
properties: {
// 必传参: 对应每项的参数们
item: {
required: true,
type: Object,
value: {}
}
},
})
tada~回头完善掉开篇的bug我们再来哟
网友评论