<script setup>
import {computed, ref} from "vue";
const images = ref([
{
type: '环境传感器',
name: '环境传感器',
modelName: 'env_data',
dateLabel: '环境数据',
data: [
{fieldName: 'temperature', fieldLabel: '温度', unit: '℃'},
{fieldName: 'humidity', fieldLabel: '湿度', unit: '%'},
{fieldName: 'co2', fieldLabel: '二氧化碳', unit: 'ppm'},
{fieldName: 'pm25', fieldLabel: 'PM2.5', unit: 'μg/m3'},
{fieldName: 'pm10', fieldLabel: 'PM10', unit: 'μg/m3'},
{fieldName: 'no2', fieldLabel: 'NO2', unit: 'μg/m3'},
{fieldName: 'so2', fieldLabel: 'SO2', unit: 'μg/m3'},
{fieldName: 'o3', fieldLabel: 'O3', unit: 'μg/m3'},
]
},
{
type: '水表',
name: '水表',
modelName: 'water_data',
dateLabel: '水表数据',
data: [
{fieldName: 'water_flow', fieldLabel: '水流量', unit: 'L/min'},
{fieldName: 'water_level', fieldLabel: '水位', unit: 'cm'},
]
},
{
type: '电表',
name: '电表',
modelName: 'electricity_data',
dateLabel: '电表数据',
data: [
{fieldName: 'electricity_flow', fieldLabel: '电流流量', unit: 'A'},
{fieldName: 'voltage', fieldLabel: '电压', unit: 'V'},
]
},
{
type: '水表',
name: '水表',
modelName: 'water_data',
dateLabel: '水表数据',
data: [
{fieldName: 'water_flow', fieldLabel: '水流量', unit: 'L/min'},
{fieldName: 'water_level', fieldLabel: '水位', unit: 'cm'},
]
}
])
const laneCount = ref(2) // 指定泳道的数量
// 计算属性:计算每个模块分布到各个泳道,一列表示一条泳道
const lanes = computed(() => {
const lanes = new Array(laneCount.value).fill().map(() => [])
images.value.forEach((image, index) => {
const laneIndex = index % laneCount.value
lanes[laneIndex].push(image)
})
return lanes
})
// 计算属性:泳道的宽度
const laneWidth = computed(() => {
return 100 / laneCount.value
})
</script>
<template>
<div class="waterfall-container">
<!-- 创建每个泳道,lanes 数组中的每个元素都代表一个泳道 -->
<div
v-for="(lane, index) in lanes"
:key="index" class="lane"
:style="{ width: laneWidth + '%' }">
<!-- 创建每个瀑布流项,flowItem 模块的内容和高度 -->
<el-card
v-for="(flowItem, flowIndex) in lane"
:key="flowIndex" class="item"
:style="{ height: flowItem.height + 'px' }">
<template #header>
<div class="card-header">
<span> 传感器类型:{{ flowItem.type }}</span>
<span> 传感器设备:{{ flowItem.name }}</span>
<span> 数据表:{{ flowItem.modelName }}</span>
<span> 数据别名:{{ flowItem.dateLabel }}</span>
</div>
</template>
<div class="main">
<div v-for="item in flowItem.data" :key="item" class="content">
<span>key值:{{item.fieldName}}</span>
<span>数据表字段:{{item.fieldLabel}}</span>
<span>单位:{{item.unit}}</span>
</div>
</div>
</el-card>
</div>
</div>
</template>
<style scoped lang="scss">
.waterfall-container {
display: flex;
flex-wrap: wrap;
}
.lane {
display: flex;
flex-direction: column;
}
.item {
margin: 6px;
border-radius: 8px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
overflow: hidden;
transition: transform 0.3s ease, box-shadow 0.3s ease;
&:hover {
transform: translateY(-5px);
box-shadow: 0 8px 16px rgba(0, 0, 0, 0.2);
}
}
.card-header {
background-color: #f4f7fa;
padding: 10px 15px;
font-size: 14px;
font-weight: bold;
}
.card-header span {
display: block;
margin-bottom: 5px;
color: #333;
}
.main {
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.content {
border: 1px solid #b5efed;
border-radius: 8px;
padding: 6px;
width: calc(33.3% - 4px);
display: flex;
flex-direction: column;
background-color: #f9f9f9;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
transition: background-color 0.3s ease, box-shadow 0.3s ease;
&:hover {
background-color: #f0f8ff;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
}
.content span {
display: flex;
margin-bottom: 8px;
color: #666;
line-height: 1.5;
}
.content span:first-child {
font-weight: bold;
color: #333;
}
.content span:last-child {
color: #1a73e8;
}
</style>
2. v-masonry
2.1 什么是v-masonry
Vue-Masonry 是一个用于 Vue.js 的瀑布流布局插件,它基于 Masonry 布局库,可以帮助你创建灵活的、瀑布流风格的网格布局。这种布局常用于展示不同高度的项目,使它们以整齐的方式排列在网页上。
2.2 v-masonry主要特点和用法
易于使用:Vue-Masonry 提供了简单的 Vue 组件,只需将项目包装在 标签内,就可以轻松地实现瀑布流布局。
自适应布局:Vue-Masonry 自动处理项目的高度不一致,确保它们在网格中以最佳方式排列。
可定制性:你可以通过设置属性来自定义布局,例如指定列数、列之间的间距、项目之间的间距等。
动态添加项目:你可以在 Vue 组件中动态添加或移除项目,Vue-Masonry 会自动重新排列项目,而无需手动干预。
响应式设计:Vue-Masonry 可以适应不同屏幕尺寸,从而在移动设备和桌面设备上都具有良好的显示效果。
支持过渡动画:你可以通过 Vue 的过渡动画系统为项目添加过渡效果,使项目的添加和移除更加平滑。
2.3 安装及使用
npm install vue-masonry --save
yarn add vue-masonry
导入
// 在你的组件中导入 Vue Masonry
import VueMasonry from 'vue-masonry';
// 注册 Vue Masonry 插件
Vue.use(VueMasonry);
使用
<template>
<div v-masonry class="container" :options="masonryOptions">
<div
v-masonry-tile
v-for="(item, index) in items"
:key="index"
:style="{
width: `${100 / imagePerRow}%`
}"
>
<!-- 你的元素内容 -->
</div>
</div>
</template>
<script>
export default {
data() {
return {
items: [
// 你的项目数据
],
imagePerRow: 3, // 设置每行显示的图片数量,可以根据需要更改
masonryOptions: {
// 可以在此添加其他配置选项
},
};
}
}
</script>
参考文献
参考文章链接:https://blog.youkuaiyun.com/qq_51137480/article/details/133858816