vue简易瀑布流

发布时间:2024年01月19日

主要代码

	<div class="falls-list" :style="{ 'min-height': `${minHeight}px` }" ref="falls">
		<div class="falls-tempate" ref="node">
			<slot :item="item" type="t"> </slot>
		</div>
		<div class="falls-box">
			<div class="falls-left" ref="fallsLeft">
				<div v-for="item in left.list" :key="item.id">
					<slot :item="item" type="l"> </slot>
				</div>
			</div>
			<div class="falls-right" ref="fallsRight">
				<div v-for="item in right.list" :key="item.id">
					<slot :item="item" type="r"> </slot>
				</div>
			</div>
		</div>
	</div>
</template>

<script>
export default {
	name: "falls-list",
	props: {
		goodsList: {
			type: Array,
			default: () => [],
		},
	},
	data() {
		return {
			left: {
				list: [],
				height: 0,
			},
			right: {
				list: [],
				height: 0,
			},
			list: [],
			item: {},
			callback: () => {},
			minHeight: 0,
		};
	},
	watch: {
		goodsList: {
			deep: true,
			handler(n) {
				// 因为会有中间插入和清除前面数据的情况,所以直接清空重新设置,为了页面不在过程中波动,需要给个高度撑开盒子
				// 可以的话还是推荐用addList方法
				if (this.$refs.fallsLeft) {
					this.minHeight = this.$refs.fallsLeft.clientHeight;
				}
				console.log(this.minHeight)
				this.list = n.slice(0);
				this.right = {
					list: [],
					height: 0,
				};
				this.left = {
					list: [],
					height: 0,
				};
				console.log(this.list);
				this.distribute();
			},
		},
	},
	methods: {
		getNode() {
			return [
				...this.$refs.fallsLeft.childNodes,
				...this.$refs.fallsRight.childNodes,
			];
		},
		addList(msg) {
			let { list = [], replace = false, fn = () => {} } = msg;
			if (replace) {
				this.list = list;
			} else {
				this.list.push(...list.map((item) => item));
			}
			this.callback = fn;
			this.distribute();
		},
		distribute() {
			if (this.list.length) {
				this.item = this.list.shift();
				this.$nextTick(() => {
					this.handleNode(this.$refs.node.childNodes[0]);
				});
			} else {
				this.callback();
				this.minHeight = 0
				this.$emit("end");
			}
		},
		handleNode(node) {
			if (!node) {
				return;
			}
			if (this.left.height > this.right.height) {
				this.right.list.push(this.item);
				this.right.height += node.clientHeight;
			} else {
				this.left.list.push(this.item);
				this.left.height += node.clientHeight;
			}
			this.distribute();
		},
	},
	created() {
		this.goodsList.splice(0, 0); //处理第一次赋值没更新的问题
	},
	mounted() {},
	beforeDestroy() {},
};
</script>

<style scoped>
.falls-tempate > div {
	height: 1px;
	position: fixed;
	bottom: -1px;
	overflow: hidden;
}
.falls-box {
	display: flex;
	flex-wrap: wrap;
	justify-content: space-between;
}
</style>

用法

<template>
    <falls-list :goods-list="goodsList" v-slot="{ item }">
        <div>
            你的单个组件{{item}}
	</div>
    </falls-list>
</template>
<script>
import FallsList from "./FallsList.vue";
export default {
    components: { FallsList },
    data() {
	return {
          goodsList:[]
         }
       }
    }
 </script>     

或者

<template>
    <falls-list ref="fallsList v-slot="{ item }">
        <div>
            你的单个组件{{item}}
	</div>
    </falls-list>
</template>
<script>
import FallsList from "./FallsList.vue";
export default {
    components: { FallsList },
    methods: {
        add(){
            this.$refs.fallsList.addList({ list });
        }
    }
}
 </script>     
文章来源:https://blog.csdn.net/weixin_43110440/article/details/135694221
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。