天天看點

uni-app 實作瀑布流 最簡潔方案瀑布流實作效果實作思路代碼了解目前已封裝為元件 傳入參數list即可直接使用。因使用場景不同css自己因情況各自書寫 這裡就不羅列了 本文章主要分享實作思路 了解之後可以做到舉一反三

瀑布流實作效果

uni-app 實作瀑布流 最簡潔方案瀑布流實作效果實作思路代碼了解目前已封裝為元件 傳入參數list即可直接使用。因使用場景不同css自己因情況各自書寫 這裡就不羅列了 本文章主要分享實作思路 了解之後可以做到舉一反三

實作思路

同樣采用常見的兩欄瀑布流布局,分别用數組goodsLeftList和goodsRightList儲存左右兩欄要渲染對象, 初始化時,加載一張圖檔,然後依次把圖檔加到欄高更低的一欄中。 主要使用的是image的@load事件。每次通過計算放入左右清單 儲存所有對象的數組将該對象删除 圖檔加載完畢觸發下個子產品實作懶加載的效果

代碼了解

<view class="waterfall_left"  >
	<view class="waterfall_list" v-for="(item,index) in goodsLeftList" :key="index" ">
		<view class="waterfall_list_img">
			<image :src="item.goods_main_pic" mode="widthFix" @load="considerPush"></image>
		</view>
		<view class="msg-box">
			<view class="name single-omit">{{item.goods_name}}</view>
			<view class="price-box flex-align-center">
				<view class="unit"><text>¥</text>{{item.goods_sku.sku_sale_price}}</view>
			</view>
		</view>
	</view>
</view>
<view class="waterfall_right"  >
	<view class="waterfall_list" v-for="(item,index) in goodsRightList" :key="index">
		<view class="waterfall_list_img">
			<image :src="item.goods_main_pic" mode="widthFix" @load="considerPush"></image>
		</view>
		<view class="msg-box">
			<view class="name single-omit">{{item.goods_name}}</view>
			<view class="price-box flex-align-center">
				<view class="unit"><text>¥</text>{{item.goods_sku.sku_sale_price}}</view>
			</view>
		</view>
	</view>
</view>

<script>
export default {
	props: {
		list: { type: Array, required: true },
	},
	data() {
		return {
			// 左側商品清單
			goodsLeftList:[],
			// 右側商品清單
			goodsRightList:[],
			// 元件資料備份
			newList:[],
		}
	},
	created() {
		this.touchOff();// 觸發排列
	},
	mounted(){},
	watch: { 
		list(newValue, oldValue) {
			this.touchOff()
		},
	},
	computed:{},
	methods: {
		// 觸發重新排列
		touchOff(){
			this.newList = [...this.list];
			this.goodsLeftList = [];
			this.goodsRightList = [];
			if(this.newList.length != 0){
				this.goodsLeftList.push(this.newList.shift());//觸發排列
			}
			
		},
		// 計算排列
		considerPush(){
			if(this.newList.length == 0)return;//沒有資料了
			let leftH = 0,rightH = 0;//左右高度
			var query = uni.createSelectorQuery().in(this);
			query.selectAll('.waterfall_left').boundingClientRect()
			query.selectAll('.waterfall_right').boundingClientRect()
			query.exec(res=>{
				leftH = res[0].length != 0 ? res[0][0].height : 0;//防止查詢不到做個處理
				rightH = res[1].length != 0 ? res[1][0].height : 0;
				if(leftH == rightH || leftH < rightH){
					// 相等 || 左邊小  
					this.goodsLeftList.push(this.newList.shift());
				}else{
					// 右邊小
					this.goodsRightList.push(this.newList.shift());
				}
			});
		},
	}
}
</script>
           

目前已封裝為元件 傳入參數list即可直接使用。因使用場景不同css自己因情況各自書寫 這裡就不羅列了 本文章主要分享實作思路 了解之後可以做到舉一反三