关于小程序和APP的瀑布流组件的封装

关于小程序和APP的瀑布流组件的封装

运行效果 :

在这里插入图片描述在这里插入图片描述

不多说上代码 :

<!-- 瀑布流组件 -->
<template>
	<view class="water-fall-flow">
		<scroll-view class="content" :style="{height : contentH + 'px'}" scroll-y="true" @scrolltolower="loadMore"
		 lower-threshold="10">
			<!--瀑布流布局start-->
			<view class="new-list">
				<view class="list-left">
					<view class="card" v-for="(item, index) in cardListLeft" :key="index">
						<image :src="item.cardImg" alt="" mode="widthFix" width="100%" @load="onImageLoad" />
						<view class="card-text">
							<view>{{ item.cardTitle }}</view>
							<view>{{ item.cardText }}</view>
						</view>
					</view>
				</view>
				<view class="list-right">
					<view class="card" v-for="(item, index) in cardListRight" :key="index">
						<image :src="item.cardImg" alt="" mode="widthFix" width="100%" @load="onImageLoad" />
						<view class="card-text">
							<view>{{ item.cardTitle }}</view>
							<view>{{ item.cardText }}</view>
						</view>
					</view>
				</view>
			</view>
			<view class="noMore" v-if="showNoMore">我也是有底线的!!!</view>
			<!--瀑布流布局end-->
		</scroll-view>
	</view>
</template>

<script>
	export default {
		props: {
			allcardList: {
				type: Array,
				default () {
					return []
				}
			}
		},
		data() {
			return {
				// 左栏card
				cardListLeft: [],
				// 右栏card
				cardListRight: [],
				//分别是左右栏的高度
				cardLeftHeight: 0,
				cardRightHeight: 0,
				//作为card的ID
				cardListItem: 0,
				//实际载入的card的高度
				rImgH: 0,
				//作为scoll滚动触底,加载更多的标记,防止多次出发事件,1为允许,0为阻止
				loadMoreTemp: 1,
				//控制底部“我也是有底线view的显示”
				showNoMore: false,
				// 存放加载好的card
				cardList: [],
				// 自适应屏幕高度 ,默认高度是800
				contentH: 800
			}
		},
		created() {
			this.waterfall();
		},
		methods: {
			// 加载图片 同时计算相对应的高度
			onImageLoad(e) {
				// e为相关照片属性信息
				//实际显示的单栏宽度,345upx
				let divWidth = 345;
				//图片原始宽度
				let oImgW = e.detail.width;
				//图片原始高度
				let oImgH = e.detail.height;
				//重新计算当前载入的card的高度
				let rImgH = (divWidth * oImgH) / oImgW + 170;
				// 判断是否为第一张card
				if (this.cardListItem == 0) {
					// 第一张card的高度加到左边的高度去
					this.cardLeftHeight += rImgH;
					//card索引加1
					this.cardListItem++;
					// 把第二张card添加到右边栏
					// this.cardListRight.push(this.cardList[this.cardListItem])
				} else {
					//card索引加1
					this.cardListItem++;
					// 判断那边高度低就加到那边
					if (this.cardLeftHeight > this.cardRightHeight) {
						this.cardRightHeight += rImgH;
					} else {
						this.cardLeftHeight += rImgH;
					}
					//根据目前的栏高,把下一张card,push到低的那栏
					if (this.cardListItem < this.cardList.length) {
						if (this.cardLeftHeight > this.cardRightHeight) {
							this.cardListRight.push(this.cardList[this.cardListItem])
						} else {
							this.cardListLeft.push(this.cardList[this.cardListItem])
						}
					}
				}
				//每次载入的card数量设置为4,只有载入完成才允许下一次的scroll触底,触发loadMore
				if (this.cardListItem % 4 == 0) {
					this.loadMoreTemp = 1;
				}
			},
			waterfall() {
				// 先取4条
				this.cardList = this.allcardList.slice(0, 4);
				// 把第一个加到左边栏
				this.cardListLeft.push(this.cardList[0]);
				this.cardListRight.push(this.cardList[1]);
				//利用uni-APP获取系统信息Api,获取客户端的屏幕高度,设置成scoll-view的高度,实现触底事件+
				uni.getStorageInfo({
					success(res) {
						this.contentH = res.windowHeight;
					}
				})
			},
			// 加载更多
			loadMore() {
				// 判断是否允许滚动   loadMoreTemp==1,才允许触发
				if (this.loadMoreTemp == 1) {
					//防止多次触发
					this.loadMoreTemp = 0;
					// 定义一个新的数组,存放更新的card数组  ==> 每次滚动加载4条
					let newcardList = this.allcardList.slice(this.cardListItem, this.cardListItem + 4);
					// 判断是否有有新数据
					if (newcardList.length != 0) {
						// 新数据加载到cardList后面
						this.cardList = this.cardList.concat(newcardList);
						//把第一个新数据加到目前更低的栏上,以触发@load="onImageLoad"
						if (this.cardLeftHeight > this.cardRightHeight) {
							this.cardListRight.push(newcardList[0])
						} else {
							this.cardListLeft.push(newcardList[0])
						}
					}
					// 判断当当前cardList和allcardList长度相等就代表全部加载完了
					if (this.cardList.length == this.allcardList.length) {
						this.showNoMore = true;
					}
				}
			}
		}
	}
</script>

<style lang="scss" scoped>
	.new-list {
		// clear: both;
		// overflow: hidden;
		// height: 100%;
		margin: 15upx;
		display: flex;
		justify-content: space-between;
		>view {
			width: 49%;
			// &.list-left {
			// 	float: left;
			// }
			// &.list-right {
			// 	float: right;
			// }
			.card {
				width: 100%;
					background-color: aliceblue;
				border-radius: 40upx;
				overflow: hidden;
				margin-bottom: 15upx;
				>image {
					width: 100%;
				}
			}

			.card-text {
				width: 100%;
				padding: 10upx;

				>view:nth-child(1) {
					font-size: 35upx;
					color: brown;
				}

				>view:nth-child(2) {
					font-size: 28upx;
					 overflow: hidden;
					text-overflow: ellipsis;
					display: -webkit-box;
					-webkit-line-clamp:3;
					-webkit-box-orient: vertical;
				}
			}
		}

		
	}
	.noMore {
		background-color: cornsilk;
		color: darkgray;
		text-align: center;
		height: 50upx;
	}
</style>

父组件的调用:

<template>
	<view class="app">
		<waterfall-flow :allcardList="allcardList"></waterfall-flow>
	</view>
</template>
<script>
import waterfallFlow from '@/components/common/waterfallFlow';
	export default {
		components:{
			waterfallFlow
		},
		data(){
			return{
				allcardList: [{
						cardImg: '../../static/01.jpeg',
						cardTitle: '我是第一张图片',
						cardText: '来见识我的瀑布流啊来见识我的瀑布流啊来见识我的瀑布流啊来见识我的瀑布流啊来见识我的瀑布流啊'
					},
					{
						cardImg: '../../static/03.jpeg',
						cardTitle: '我是第二张图片',
						cardText: '来见识我的瀑布流啊来见识我的瀑布流啊来见识我的瀑布流啊来见识我的瀑布流啊来见识我的瀑布流啊'
					},
					{
						cardImg: '../../static/02.jpeg',
						cardTitle: '我是第三张图片',
						cardText: '来见识我的瀑布流啊来见识我的瀑布流啊来见识我的瀑布流啊来见识我的瀑布流啊'
					},
					{
						cardImg: '../../static/01.jpeg',
						cardTitle: '我是第四张图片',
						cardText: '来见识我的瀑布流啊来见识我的瀑布流啊来见识我的瀑布流啊来见识我的瀑布流啊'
					},
					{
						cardImg: '../../static/04.jpeg',
						cardTitle: '我是第五张图片',
						cardText: '来见识我的瀑布流啊来见识我的瀑布流啊来见识我的瀑布流啊来见识我的瀑布流啊'
					}
				]
			}
		}
	}
</script>

这是我本人第一次写博客,请大家多多指教. —>> 大宝

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值