Vue3实现简单的瀑布流效果,可抽离成组件直接使用

先来看下效果图

瀑布流中的内容可进行自定义,这里的示例图是通过不同背景颜色的展示进行区分,每个瀑布流中添加了自定义图片和文字描述。

实现方式:

1.建立子组件(可单独抽离)写出瀑布流的样式

文件名为waterFall.vue

<template>
	<div class="list">
		<div
			class="item"
			v-for="(item, index) in waterList"
			:style="{
				width: width + 'px',
				height: item.height + 'px',
				left: item.left + 'px',
				top: item.top + 'px',
				background: item.background,
			}"
		>
			<img :src="item.image" :alt="item.text" />
			<p class="text-box">{{ item.text }}</p>
		</div>
	</div>
</template>
<script setup>
import { ref, reactive, onMounted } from 'vue';
const props = defineProps({
	list: {
		type: Array,
		default: () => {
			return [];
		},
	},
});

// 图片宽度
const width = 120;
// 图片上下间距
const gap = 20;
// 瀑布流数组
const waterList = ref([]);
// 列高度数组
const heightList = reactive([]);

// 屏幕宽度需要在 mounted 之后拿到
onMounted(() => {
	// 计算列数
	const column = Math.floor(document.body.clientWidth / width);
	// 核心内容就是维护每个图片的 left、top
	for (let i = 0; i < props.list.length; i++) {
		// 先铺上第一行(i < column 则表示是第一行)
		if (i < column) {
			props.list[i].top = 0;
			props.list[i].left = width * i;
			// 塞进瀑布流
			waterList.value?.push(props.list[i]);
			// 高度数据更新
			heightList[i] = props.list[i].height;
		}

		// 后面的就要一张张塞进去,每次找出最低的列往里塞
		else {
			// 最低的高度,先默认为第一列高度
			let current = heightList[0];
			// 最低的列,先默认为第一个
			let col = 0;

			// 循环每一列进行比较
			heightList.forEach((h, i) => {
				if (h < current) {
					current = h;
					col = i;
				}
			});
			console.log('最低的列', col, '高度为', current);

			// 由此计算出该图片的 left、top
			props.list[i].left = col * width;
			props.list[i].top = current + gap;
			// 塞进瀑布流
			waterList.value.push(props.list[i]);

			// 更新列高度数组
			heightList[col] = current + gap + props.list[i].height;
		}
	}
	console.log('waterList', waterList.value);
	console.log('heightList', heightList);
});
</script>
<style lang="scss" scoped>
.list {
	position: relative;
	height: 100%;
	overflow-y: auto;
	width: 100%;
	.item {
		position: absolute;
		.text-box {
			font-weight: 500px;
			font-size: 18px;
			color: #000000;
		}
	}
}
</style>

2.在父组件中引入使用

父组件中引入使用,其中list为展示的瀑布流数组,class可设置当前瀑布流的一些盒子样式

<water-fall :list="list" class="water-fall" />

3.在父组件中传值实现瀑布流效果

在父组件中设置瀑布流的数据,这里为了方便展示,直接使用的样例数据,实际开发中,可根据接口来进行获取。

其中的height是指瀑布流中每一个的高度,background为背景颜色,image为自定义的图片,text为描述,以上均可根据个人需求进行自定义展示。

const list = [
	{
		height: 300,
		background: 'red',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 400,
		background: 'pink',
		text: '美术作品+沈佳宜',
		image: '/images/works-publicity/tradition.png',
	},
	{
		height: 500,
		background: 'blue',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 200,
		background: 'green',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 300,
		background: 'gray',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 400,
		background: '#CC00FF',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 200,
		background: 'pink',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 100,
		background: '#996666',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 300,
		background: 'gray',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 400,
		background: '#CC00FF',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 200,
		background: 'gray',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 100,
		background: '#996666',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 300,
		background: 'gray',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 400,
		background: '#CC00FF',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 200,
		background: 'gray',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 100,
		background: '#996666',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 300,
		background: 'gray',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	},
	{
		height: 400,
		background: '#CC00FF',
		image: '/images/works-publicity/tradition.png',
		text: '平面作品+李宇轩',
	}
];
相关推荐
理想不理想v9 分钟前
vue经典前端面试题
前端·javascript·vue.js
不收藏找不到我10 分钟前
浏览器交互事件汇总
前端·交互
小阮的学习笔记23 分钟前
Vue3中使用LogicFlow实现简单流程图
javascript·vue.js·流程图
YBN娜24 分钟前
Vue实现登录功能
前端·javascript·vue.js
阳光开朗大男孩 = ̄ω ̄=24 分钟前
CSS——选择器、PxCook软件、盒子模型
前端·javascript·css
杨荧26 分钟前
【JAVA毕业设计】基于Vue和SpringBoot的服装商城系统学科竞赛管理系统
java·开发语言·vue.js·spring boot·spring cloud·java-ee·kafka
minDuck28 分钟前
ruoyi-vue集成tianai-captcha验证码
java·前端·vue.js
小政爱学习!1 小时前
封装axios、环境变量、api解耦、解决跨域、全局组件注入
开发语言·前端·javascript
魏大帅。1 小时前
Axios 的 responseType 属性详解及 Blob 与 ArrayBuffer 解析
前端·javascript·ajax