当前位置: 首页 > backend >正文

vue3实现可视化大屏布局

实现功能:
1 实现4x3宫格布局,
2 自定义设置跨行,跨列自动隐藏对应列,比如setAreaSpanAndUpdateVisibility(2, 3, 2); 表示设置区域2,跨3行,跨2列,然后区域3,6,7,10,11自动隐藏
3 内容自动剧中

1 效果图

在这里插入图片描述

代码

<template><div class="visual-root big-data-bg-qjg-v1"><div class="top-bar">数据可视化大屏 - 顶部区域</div><div class="grid-area"><template v-for="(item, _idx) in gridItems" :key="item.id"><div class="grid-cell" v-if="item.visible" :style="getGridStyle(item)"><div class="cell-title"><div class="title-bg"></div><span>{{ item.id }}-{{ item.title }}</span></div><divclass="cell-content" :style="getContentSpanStyle(item)"><div v-if="item.component === 'ChartCell'"><ChartCell></ChartCell></div><div v-else-if="item.component === 'TableCell'"><TableCell></TableCell></div><div v-else-if="item.component === 'TextCell'"><TextCell></TextCell></div></div></div></template></div><!-- <button class="test-btn" @click="testSpan">测试区域122</button> --></div>
</template><script setup lang="ts">
import GridCell from "./components/GridCell.vue.vue";
import ChartCell from "./components/ChartCell.vue";
import TableCell from "./components/TableCell.vue";
import TextCell from "./components/TextCell.vue";
import { onMounted, ref } from "vue";const gridItems = ref([{id: 1,title: "区域1",color: "#4fdcff",visible: true,row: 1,col: 1,rowspan: 1,colspan: 1,component: "ChartCell",},{id: 2,title: "区域2",color: "#ffe066",visible: true,row: 1,col: 2,rowspan: 1,colspan: 1,component: "TableCell",},{id: 3,title: "区域3",color: "#ff8c66",visible: true,row: 1,col: 3,rowspan: 1,colspan: 1,component: "TextCell",},{id: 4,title: "区域4",color: "#6fff8f",visible: true,row: 1,col: 4,rowspan: 1,colspan: 1,component: "TextCell",},{id: 5,title: "区域5",color: "#a066ff",visible: true,row: 2,col: 1,rowspan: 1,colspan: 1,component: "TextCell",},{id: 6,title: "区域6",color: "#ff66c4",visible: true,row: 2,col: 2,rowspan: 1,colspan: 1,component: "TextCell",},{id: 7,title: "区域7",color: "#66e0ff",visible: true,row: 2,col: 3,rowspan: 1,colspan: 1,component: "TextCell",},{id: 8,title: "区域8",color: "#ffb366",visible: true,row: 2,col: 4,rowspan: 1,colspan: 1,component: "TextCell",},{id: 9,title: "区域9",color: "#b3ff66",visible: true,row: 3,col: 1,rowspan: 1,colspan: 1,component: "TextCell",},{id: 10,title: "区域10",color: "#ff6666",visible: true,row: 3,col: 2,rowspan: 1,colspan: 1,component: "TextCell",},{id: 11,title: "区域11",color: "#66ffb3",visible: true,row: 3,col: 3,rowspan: 1,colspan: 1,component: "TextCell",},{id: 12,title: "区域12",color: "#668cff",visible: true,row: 3,col: 4,rowspan: 1,colspan: 1,component: "TextCell",},
]);function setAreaSpanAndUpdateVisibility(areaId: number,rowspan: number,colspan: number,
) {const area = gridItems.value.find((item) => item.id === areaId);if (!area) return;area.rowspan = rowspan;area.colspan = colspan;// gridItems.value.forEach(item => { item.visible = true })for (let r = 0; r < rowspan; r++) {for (let c = 0; c < colspan; c++) {if (r === 0 && c === 0) continue;const coverRow = area.row + r;const coverCol = area.col + c;const coveredItem = gridItems.value.find((item) => item.row === coverRow && item.col === coverCol,);if (coveredItem) coveredItem.visible = false;}}
}function getGridStyle(item: any) {return {gridRow: `${item.row} / span ${item.rowspan || 1}`,gridColumn: `${item.col} / span ${item.colspan || 1}`,background: item.color,};
}
function getContentSpanStyle(item: any) {return;const style: any = {};if (item.rowspan > 1)style.height = `calc(100% * ${item.rowspan} + ${(item.rowspan - 1) * 18}px)`;if (item.colspan > 1)style.width = `calc(100% * ${item.colspan} + ${(item.colspan - 1) * 18}px)`;return style;
}onMounted(() => {setAreaSpanAndUpdateVisibility(2, 3, 2);
});
</script><style scoped>
.visual-root {width: 100vw;height: 100vh;min-width: 800px;min-height: 600px;background: linear-gradient(120deg, rgba(10, 26, 42, 0.8) 60%, rgba(24, 60, 90, 0.8) 100%), url('@/assets/imgs/background.jpg');background-size: cover;background-position: center;background-repeat: no-repeat;overflow: hidden;font-family: "Microsoft YaHei", Arial, sans-serif;color: #fff;display: flex;flex-direction: column;
}
.top-bar {width: 100%;height: 100px;background: linear-gradient(90deg, #1e2a3a 60%, #223c5a 100%);color: #4fdcff;font-size: 36px;font-weight: bold;letter-spacing: 8px;text-align: center;line-height: 100px;box-shadow: 0 2px 12px #0008;z-index: 10;flex-shrink: 0;
}
.grid-area {flex: 1;width: 100%;display: grid;grid-template-columns: repeat(4, 1fr);grid-template-rows: repeat(3, 1fr);gap: 18px;padding: 28px 32px 32px 32px;box-sizing: border-box;align-items: stretch;justify-items: stretch;
}
.grid-cell {border-radius: 18px;box-shadow: 0 0 18px #0004;display: flex;flex-direction: column;min-width: 0;min-height: 0;overflow: hidden;position: relative;transition: box-shadow 0.2s;background: var(--cell-color, #4fdcff);
}
.grid-cell:hover {box-shadow:0 0 32px #fff8,0 2px 12px #0008;z-index: 2;
}
.cell-title {position: relative;font-size: 22px;font-weight: bold;padding: 0;color: #fff;text-shadow: 0 0 8px #000a;height: 48px;display: flex;align-items: center;z-index: 1;
}
.cell-title .title-bg {position: absolute;left: 0;top: 0;right: 0;bottom: 0;z-index: 0;background:url("https://img.alicdn.com/imgextra/i2/O1CN01Qw6QwB1wQw6QwB1wQw6QwB1wQw.png")no-repeat center/cover,linear-gradient(90deg, #0008 0%, #fff2 100%);opacity: 0.18;border-bottom: 2px solid #fff2;border-radius: 0 0 16px 16px;
}
.cell-title span {position: relative;z-index: 1;padding: 0 18px;line-height: 48px;
}
.cell-content {flex: 1;padding: 18px;overflow: auto;font-size: 18px;color: #fff;background: rgba(0, 0, 0, 0.04);transition: width 0.3s, height 0.3s;display: flex;align-items: center;justify-content: center;
}
.cell-content-hide {display: none;
}
</style>
http://www.xdnf.cn/news/15943.html

相关文章:

  • Redis入门教程(一):基本数据类型
  • k8s知识点
  • 3x3矩阵教程
  • 第十八节:第七部分:java高级:注解的应用场景:模拟junit框架
  • 如何用纯 HTML 文件实现 Vue.js 应用,并通过 CDN 引入 Element UI
  • Python 进阶(七):XML 基本操作
  • 【编程语言】C、C++、C#深度对比:三种语言的演进历程与应用场景
  • Java 大视界 -- 基于 Java 的大数据分布式计算在地球物理勘探数据处理与地质结构建模中的应用(356)
  • numpy库的基础知识
  • oracle 数据库中,将几张表的数据按指定日期范围实时同步至同一个数据库的备份表中。
  • CLIP与SIGLIP对比浅析
  • 小架构step系列21:参数和返回值的匹配
  • FastAPI 中,数据库模型(通常使用 SQLAlchemy 定义)和接口模型(使用 Pydantic 定义的 schemas)的差异
  • 【智能协同云图库】智能协同云图库第二期:基于腾讯云 COS 对象存储—开发图片各功能模块
  • SQLite以及Room框架的学习:用SQLite给新闻app加上更完善的登录注册功能
  • 蜂窝物联网模组市场新展望:中国企业继续保持最强竞争力
  • 进阶向:基于Python的电脑硬件监控工具(GUI + 系统信息采集)
  • 51c大模型~合集157
  • 138. Java 泛型 - 通配符捕获Helper程序方法:类型安全解决方案
  • 二维码扫描登录流程详解
  • 【设计模式】迭代器模式 (游标(Cursor)模式)
  • JavaEE初阶第十期:解锁多线程,从 “单车道” 到 “高速公路” 的编程升级(八)
  • WinUI3开发_Frame用法
  • 服务器设置国外IP无法访问对防御攻击有用吗?
  • 一文详解REST风格
  • 一个适合MCU的分级菜单框架
  • .NET SDK 9.0.200引入对SLNX解决方案文件的支持
  • django filter按两个属性 去重
  • Linux——自制shell命令行解释器
  • 【LeetCode 热题 100】208. 实现 Trie (前缀树)