实现方式
1.flex配合js
原理
列表提前加载一次,计算高度,然后分别加入左右两个列表,最后渲染两个列表
先加载
export default defineComponent({
setup() {
const loadRef = ref(null)
const state = reactive({
loading: false,
finished: false,
params: {
pageSize: 10,
pageNo: 0
},
dataList: [],
left: {
list: [],
height: 0
},
right: {
list: [],
height: 0
},
total: 0
})
const onLoad = async () => {
try {
state.loading = true
const {
data: { data, total}
} = await FetchDataList(state.params)
// 用于提前加载
state.dataList = data
state.total = total
state.params.pageNo++
nextTick(() => {
// 获取提前加载的dom
const arr = loadRef.value.querySelectorAll('.item')
datas.forEach((e, i) => {
// 实际展示的列表,根据高度判断push到对应数组
const listName =
state.left.height <= state.right.height ? 'left' : 'right'
state[listName].list.push(e)
state[listName].height += arr[i].offsetHeight
})
})
} finally {
state.loading = false
}
}
return {
lecturer,
onLoad,
...toRefs(state)
}
},
render() {
return (
<List
vModel={this.loading}
finished={this.finished}
onLoad={this.onLoad}
immediate-check={true}
>
<!-- 提前渲染的内容 -->
<div
ref="loadRef"
style="opacity: 0;position: fixed; left: -999px;top: -999px"
>
{this.dataList.map(e => (
<Item data={e} />
))}
</div>
<!-- 实际展示的内容 -->
<div class="container">
<div>
{this.left.list.map(e => (
<Item data={e} />
))}
</div>
<div>
{this.right.list.map(e => (
<Item data={e} />
))}
</div>
</div>
</List>
)
}
})
// style
.container {
display: flex;
padding: 15px 15px 0;
justify-content: space-between;
& > div {
width: 168px;
display: flex;
flex-wrap: wrap;
flex-direction: column;
counter-reset: items;
min-height: 100vh;
}
}
优点
- 可以应对内容高度未知的情况
- 可以分页
缺点
- 需要计算,性能有损耗
2.flex
.container{
display: flex;
flex-wrap: wrap;
flex-direction: column;
height: 800px;
}
优点
- 无需js配合
缺点
- 需要提前知道内容高度,并设置容器高度
- 不支持分页
3.column-count
.container{
column-count: 2;
.item {
break-inside: avoid;
}
}
优点
- 无需js配合
- 简单,不需要知道内容高度,不需要设置容器高度
缺点
- 不支持分页(分页时新加载的内容会展示在第二列的最上面)
网友评论