组件components>waterfallFlow>waterfallFlow

<template>
	<view>
		<view class="flow-box" :style="'height: ' + loadingTop + 'rpx'" ref="flow_box">
			<!-- <empty v-if="newList.length === 0"></empty> -->
			<empty v-show="isShowEmpty"></empty>
			<view v-for="(item, index) in newList" :key="item.ProductId" class="item good_item"
				v-show="positionList[item.ProductId].imageLoad"
				:class="positionList[item.ProductId].right ? 'right' : 'left'"
				:style="{top: positionList[item.ProductId].top + 'rpx'}" @click="onPageJump(item.ProductId)">
				<view class="goods_img">
					<image :data-id="item.ProductId" @load="onImageLoad" :src="item.MainImageUrl_Real" mode="widthFix"  @error="imgerror($event, index)">
					</image>
				</view>
				<view class="title">{{ item.ProductName }}</view>
				<!-- <view class="goods_cont">{{item.Desc}}</view> -->
				<!-- <view class="club" v-if="item.type">
					<text class="goods_money_old">原价 ¥{{item.MinPrice}} </text>
					<view class="goods_money members">
						<text class="members_bg">VIP</text> ¥ {{item.MemberPrice}}
					</view>
				</view>
				<view v-else class="goods_money">原价¥ {{item.MinPrice}}</view> -->
				<view class="club">
					<text class="goods_money_old">原价¥{{item.MinPrice}} </text>
					<view class="goods_money members">
						<text class="members_bg">高级会员</text> ¥{{item.MemberPrice}}
					</view>
				</view>
			</view>
		</view>
	</view>
</template>
<script>
	const defaultData = {
		// 起始距离(rpx)
		startTop: 0,
		// 除了图片和标题以外的高度(rpx)
		// contentHeight: 20 + 22 + 20 + 20 + 20 + 10,
		contentHeight: 112,
		// 瀑布流容器宽度(rpx)
		viewWidth: 350,
		// 标题可显示宽度(rpx)
		titleWidth: 300,
		// 标题文字大小(rpx)
		titleSize: 28,
		// 容器之间的间隔Y轴(rpx)
		viewSpace: 16,
		// 列表ID参数名称
		idName: "ProductId",
		// 列表标题参数名称
		titleName: "ProductName",
	};
	// 文字换行计算行数
	function drawtext(text, maxWidth) {
		// console.log(text)
		let textArr = text.split("");
		let len = textArr.length;
		// 上个节点
		let previousNode = 0;
		// 记录节点宽度
		let nodeWidth = 0;
		// 文本换行数组
		let rowText = [];
		// 如果是字母,侧保存长度
		let letterWidth = 0;
		// 汉字宽度
		let chineseWidth = defaultData.titleSize;
		// otherFont宽度
		let otherWidth = defaultData.titleSize / 2;
		for (let i = 0; i < len; i++) {
			if (/[\u4e00-\u9fa5]|[\uFE30-\uFFA0]/g.test(textArr[i])) {
				if (letterWidth > 0) {
					if (nodeWidth + chineseWidth + letterWidth * otherWidth > maxWidth) {
						rowText.push({
							type: "text",
							content: text.substring(previousNode, i)
						});
						previousNode = i;
						nodeWidth = chineseWidth;
						letterWidth = 0;
					} else {
						nodeWidth += chineseWidth + letterWidth * otherWidth;
						letterWidth = 0;
					}
				} else {
					if (nodeWidth + chineseWidth > maxWidth) {
						rowText.push({
							type: "text",
							content: text.substring(previousNode, i)
						});
						previousNode = i;
						nodeWidth = chineseWidth;
					} else {
						nodeWidth += chineseWidth;
					}
				}
			} else {
				if (/\n/g.test(textArr[i])) {
					rowText.push({
						type: "break",
						content: text.substring(previousNode, i)
					});
					previousNode = i + 1;
					nodeWidth = 0;
					letterWidth = 0;
				} else if (textArr[i] == "\\" && textArr[i + 1] == "n") {
					rowText.push({
						type: "break",
						content: text.substring(previousNode, i)
					});
					previousNode = i + 2;
					nodeWidth = 0;
					letterWidth = 0;
				} else if (/[a-zA-Z0-9]/g.test(textArr[i])) {
					letterWidth += 1;
					if (nodeWidth + letterWidth * otherWidth > maxWidth) {
						rowText.push({
							type: "text",
							content: text.substring(previousNode, i + 1 - letterWidth)
						});
						previousNode = i + 1 - letterWidth;
						nodeWidth = letterWidth * otherWidth;
						letterWidth = 0;
					}
				} else {
					if (nodeWidth + otherWidth > maxWidth) {
						rowText.push({
							type: "text",
							content: text.substring(previousNode, i)
						});
						previousNode = i;
						nodeWidth = otherWidth;
					} else {
						nodeWidth += otherWidth;
					}
				}
			}
		}
		if (previousNode < len) {
			rowText.push({
				type: "text",
				content: text.substring(previousNode, len)
			});
		}
		return rowText.length;
	}
	let allow = true;
	export default {
		props: {
			// 数据列表
			list: {
				type: Array,
				default () {
					return [];
				}
			}
		},
		data() {
			return {
				isShowEmpty: false,
				newList: [],
				positionList: {},
				loadingTop: 0,
				leftHistoryTop: 0,
				rightHistoryTop: 0,
				imgUrl: this.$imgUrl,
			};
		},
		watch: {
			// 数据
			list: function(newVal, oldVal) {
				// console.log(newVal)
				if (newVal.length === 0) {
					this.newList = [];
					this.isShowEmpty = true;
				} else {
					this.isShowEmpty = false;
					this.newList = newVal;
					this.getCalculationPosition();
				}

			},
		},
		methods: {
			imgerror(e, index) {
				// console.log('this.newList++++++++',this.newList)
				this.newList[index].MainImageUrl_Real="https://image.zhihewei.club/FileServer/File/static/logo/zhiwei.png";
				console.log('this.newList[index]----------------',this.newList[index])
				// this.newList.splice(index, 1)
				// this.newList.splice(index, 0, '@/static/logo.png')
			},
			onPageJump(id) {
				console.log(id)
				this.$emit('onPageJump', id);
				uni.navigateTo({
					url: '../details/details2?id=' + id
				})
			},
			refreshData() {},
			// 节流
			throttle(callback, time = 400) {
				if (!allow) return false;
				allow = false;
				setTimeout(function() {
					allow = true;
					callback();
				}, time);
			},
			// 获取数据位置信息 top,right
			getCalculationPosition() {
				let leftHistoryTop = defaultData.startTop;
				let rightHistoryTop = defaultData.startTop;
				let positionList = this.positionList;
				// console.log(positionList)
				this.newList.forEach((item, index) => {
					// console.log(item)
					let currentHeight = '';
					if (item.type) {
						currentHeight = defaultData.contentHeight + 60;
					} else {
						currentHeight = defaultData.contentHeight + 60;
					}
					// console.log(currentHeight)
					// console.log(currentHeight)
					let positionItem = {};
					// 查看是否有位置数据
					// console.log(positionList[item[defaultData.idName]])
					if (positionList[item[defaultData.idName]]) {
						positionItem = positionList[item[defaultData.idName]];
					} else {
						positionList[item[defaultData.idName]] = {};
					}
					// console.log(positionItem)
					// 查看是否有图片高度数据,没有默认等宽
					// console.log(positionItem.imageHeight)
					if (positionItem.imageHeight) {
						currentHeight += positionItem.imageHeight;
						positionList[item[defaultData.idName]].imageLoad = true;
					} else {
						currentHeight += defaultData.viewWidth;
					}
					// 查看是否有标题高度数据,没有获取高度
					if (positionItem.titleHeight) {
						currentHeight += positionItem.titleHeight;
					} else {
						let titleListLen = drawtext(item[defaultData.titleName], defaultData.titleWidth);
						titleListLen = titleListLen > 2 ? 2 : titleListLen;
						positionList[item[defaultData.idName]].titleHeight = titleListLen * (defaultData
							.titleSize + 6);
						currentHeight += titleListLen * (defaultData.titleSize + 6);
					}
					if (leftHistoryTop > rightHistoryTop) {
						positionList[item[defaultData.idName]].top = rightHistoryTop;
						positionList[item[defaultData.idName]].right = true;
						positionList[item[defaultData.idName]].height = currentHeight;
						rightHistoryTop += currentHeight + defaultData.viewSpace;
					} else {
						positionList[item[defaultData.idName]].top = leftHistoryTop;
						positionList[item[defaultData.idName]].right = false;
						positionList[item[defaultData.idName]].height = currentHeight;
						leftHistoryTop += currentHeight + defaultData.viewSpace;
					}
				});
				if (leftHistoryTop > rightHistoryTop) {
					this.loadingTop = leftHistoryTop;
				} else {
					this.loadingTop = rightHistoryTop;
				}
				this.positionList = positionList;
				this.$forceUpdate();
			},
			// 图片加载完成
			onImageLoad(e) {
				// console.log(e)
				let id = e.currentTarget.dataset.id;
				let scale = defaultData.viewWidth / e.detail.width;
				let height = scale * e.detail.height;
				// console.log(scale)
				// console.log(height)
				// console.log(this.positionList[id])
				if (this.positionList[id]) {
					this.positionList[id].imageHeight = height;
				} else {
					this.positionList[id] = {
						imageHeight: height
					}
				}
				// 图片加载完刷新位置节流一下,提升性能
				this.throttle(() => {
					this.getCalculationPosition();
				}, 100);
			}
		}
	};
</script>

<style lang="scss">
	@import '@/style/mixin.scss';

	.flow-box {
		position: relative;
		color: #1a1a1a;
		box-sizing: content-box;
		top: -10rpx;
	}

	.flow-box .left {
		left: 12rpx;
	}

	.flow-box .right {
		right: 12rpx;
	}

	.flow-box .good_item {
		box-sizing: border-box;
		position: absolute;
		width: 358rpx;
		border: 2rpx solid #f9f9f9;
		background: #fff;
		border-radius: 8rpx;
		overflow: hidden;

		&.noMargin {
			margin-right: 0;
		}

		.goods_img {
			padding-bottom: 20rpx;

			image {
				width: 100%;
				display: block;
			}
		}

		.goods_cont {
			padding: 0 20rpx;
			font-size: 24rpx;
			color: #666;
			line-height: 36rpx;
			text-overflow: -o-ellipsis-lastline;
			overflow: hidden;
			text-overflow: ellipsis;
			display: -webkit-box;
			-webkit-line-clamp: 2;
			line-clamp: 2;
			-webkit-box-orient: vertical;
		}

		.title {
			font-size: 26rpx;
			padding: 0 20rpx;
			color: #333333;
			font-size: 28rpx;
			@include bov(2);
		}

		.goods_money {
			padding: 20rpx 20rpx;
			font-size: 28rpx;
			color: $my-font-color;
			font-weight: 800;
		}

		.goods_money_old {
			color: #717171;
			text-decoration: line-through;
			padding-left: 30rpx;
			padding-top: 20rpx;
			font-size: 20rpx;
		}

		.club {
			padding-top: 20rpx;

			.members {
				display: flex;
				align-items: center;
				padding-left: 30rpx;
				font-weight: 500;

				.members_bg {
					width: 84rpx;
					height: 26rpx;
					line-height: 24rpx;
					text-align: center;
					background: linear-gradient(to right, $my-left-btn-color, $my-right-btn-color);
					color: #fff;
					font-size: 16rpx;
					padding: 0;
					border-top-left-radius: 14rpx;
					border-bottom-right-radius: 14rpx;

					text {
						font-weight: normal;
					}
				}
			}
		}

	}
</style>

style>mixin.scss

@charset "utf-8";
//主题色
$themeColor: #ea552d;

@mixin theme($type,$path:''){
	@if $type == "btn_bg" {
		background-image: linear-gradient(90deg, #ea552d 0%, #f19837 100%);
	} @else if $type == "unselected_img" {
		background-image: url($path + "static/icon/ic_gender_unselected.png");
	} @else if $type == "check_img" {
		background-image: url($path + "static/icon/ic_agreed.png");
	} @else if $type == "radio_img" {
		background-image: url($path + "static/icon/ic_gender_selected.png");
	}
}
// 背景图片地址和大小
@mixin bis($url, $size: cover) {
  background-image: url($url);
  background-repeat: no-repeat;
  background-position: center center;
  background-size: $size;
}

// 头像
@mixin ic($width, $height) {
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  flex-shrink: 0;
  width: $width;
  height: $height;
}

// 单行省略号
@mixin toe() {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap
}

// 多行省略号
@mixin bov($num:2) {
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: $num;
  -webkit-box-orient: vertical;
}

更多推荐