实现一个简单的瀑布流列表

实现一个两列的瀑布流布局,支持无限滚动
**思路:**利用flex布局,将列表分为左右两侧,因为这种方式存在一个弊端,就是当有一侧的高度越来越高的时候,滑到底部的时候就会出现一个很明显的高度差,为了修复这个漏洞,写一个算法,计算每一页两侧列表的高度差,举个例子,当左侧高度比右侧高很多的时候,则把下一页列表的第一个数据放在右侧,补齐高度,反之同理;如果数据是无限滚动加载不会滑动到底部的话,则可以不做处理;

代码如下:

<template>
	<div class="prod-list">
		<van-list v-model:loading="loading" :finished="finish" finished=text="没有更多了" @load="load">
			<div class="left">
				<div id="left-box"
					<productCard v-for="productItem in productListLeft" :key="productItem.id" :itemInfo="productItem" :itemType="itemType"></productCard>
				</div>
			</div>
			<div class="right">
				<div id="right-box">
					<productCard v-for="productItem in productListRight" :key="productItem.id" :itemInfo="productItem" :itemType="itemType"></productCard>
				</div>
			</div>
		</van-list>
	</div>
</template>
<script>
import  ref  from 'vue
import { getAllstores,getAllGoods, getAllsuggest,getAllIntroduction } from '@/api/modules/goods.js'
import productCard from './productcard.vue'

export default {
	props: {
		itemType: String,
		activeClass: Number
	},
	components: {
		productCard,
		Annotate
	},
	setup(props) {
		const page = ref(0)
		const size = ref(8)
		const loading = ref(false)
		const finish = ref(false)
		const apiMap = { getAllsuggest, getAllGoods, getAllstores, getAllIntroduction }
		const productList = ref([])
		const productListLeft = ref([])
		const productListRight = ref([])
		const leftHeightNum = ref(0)
		const rightHeightNum = ref(0)
		const getContentHeight = () => {
			const leftBox = document.querySelector('#left-box')
			const rightBox = document.querySelector('#right-box')
			leftHeightNum.value = leftBox ? leftBox.offsetHeight : 0
			rightHeightNum.value = rightBox ? rightBox.offsetHeight : 0
		}
		const getorderList = (list, leftList, rightList, flag) = > {
			for(let i = 0; i < list.length; i++) {
				if (flag ===  left') {
					if (i % 2 ==0 ) {
					 	rightList.push(list[i])
				 	} else {
						leftList.push(list[i])
					} 
				} else {
					if (i % 2 == 0) {
						leftList.push(list[i])
					else {
						rightList.push(list[i])
					}
				}
			}
		}
		const getProduct = (path = 'getAllSuggest', className = 0, index) =>
			loading.value = true
			const targetApi = apiMap[path]
			const params = {
				page: page .value.
				size: size.value,
				body: 
					path !="getAllSuggest' || path != 'getAllIntroduction'
					 ? {
							goodsTypeID: className.
						} 
					: null
				
			}
			targetApi(params)
				.then(async res => {
				if (res.code === 20000) {
					if (page.value == 0) {
						productList.value = []
						productListLeft.value = []
						productListRight.value = []
					}
					let leftList = []
					let rightList = []
					productList.value = res.data.list
					finish.value = page.value >= Number(res.data.totalPages)
					if (productList.value.length > 0) {
 						await getContentHeight()
 						if (page.value === 1) {
							getorderList(productList.value, leftList, rightList, 'right')
						} else {
							if (leftHeightNum.value > rightHeightNum.value && leftHeightNum.value - rightHeightNum.value > 100) {
								let firstItem = productList.value.shift()
								rightList.push(firstItem)
								getorderList(productList.value, leftList, rightList,'left')			  	} 
							} else if ( leftHeightNum.value < rightHeightNum.value && rightHeightNum.value - leftHeightNum.value > 100) {
										let firstItem = productList.value.shift()
										leftList.push(firstItem)
										getorderList(productList.value, leftList, rightList,'right')
							} else {
								getorderList(productList.value, leftList,rightList,'right')
							}
						}
						productListLeft.value = [...productListLeft.value,...leftList]
						productListRight.value = [...productListRight.value, ...rightList]
						loading.value = false
				} else {
					loading.value=false;
					finish.value =true
				}
			})
			.catch(err => {
				loading.value=false
				finish.value =true
			})
		}
		const onLoad = () => {
			page.value += 1
			getProduct(props.itemType,props.activeClass)
		}
		// 重置数据
		const resetData = () => {
			page.value = 1
			productList.value = []
			productListLeft.value = []
			productListRight.value = []
			loading.value = false
			finish.value = false
		}
		return {
			productList,
			loadingfinish,
			onLoad,
			page,
			getProduct,
			productListLeft,
			productListRight,
			resetData,
		}
</script>
<style lang="scss"scoped>
.prod-list {
	.container {
		width: 100%;
		display: flex;
		.left {
			flex: 1;
			margin-right: 8px;
		}
		.right {
			flex: 1;
		}
	}
	.van-list {
		:deep(.van-list finished-text) {
			width: 100%;
		}
		:deep(.van-list placeholder) {
			width: 100%;
		}
	}
}
</style>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值