Files
GEAR-OA/gear-ui3/src/views/dashboard/layout.vue
2025-09-04 11:50:23 +08:00

177 lines
3.5 KiB
Vue

<template>
<div class="dashboard-layout">
<!-- 顶部导航栏 -->
<header class="layout-header">
<button
class="header-btn back-btn"
@click="handleBack"
aria-label="返回"
>
<el-icon><ArrowLeft /></el-icon>
<span>返回</span>
</button>
<h1 class="layout-title">{{ title }}</h1>
<div style="display: flex;align-items: center;gap: 10px;">
<button class="header-btn" aria-label="设置">
<el-icon><Setting /></el-icon>
<span>设置</span>
</button>
<button
class="header-btn refresh-btn"
@click="handleRefresh"
aria-label="刷新"
>
<el-icon><Refresh /></el-icon>
<span>刷新</span>
</button>
</div>
</header>
<!-- 图表内容区域 -->
<main class="charts-container">
<!-- 图表网格布局 -->
<div class="charts-grid">
<div>图表1</div>
<div>图表2</div>
<div>图表3</div>
<div>图表4</div>
</div>
</main>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { useRouter } from 'vue-router';
import { ArrowLeft, Refresh, Setting } from '@element-plus/icons-vue';
// 路由实例
const router = useRouter();
// 大屏标题
const title = ref('数据可视化大屏');
// 返回上一页
const handleBack = () => {
router.back();
};
// 刷新数据
const handleRefresh = () => {
// 这里可以实现数据刷新逻辑
// 示例:触发所有图表组件重新加载数据
const event = new CustomEvent('refresh-data');
window.dispatchEvent(event);
// 可选:添加刷新动画效果
const refreshBtn = document.querySelector('.refresh-btn i');
refreshBtn.classList.add('refreshing');
setTimeout(() => {
refreshBtn.classList.remove('refreshing');
}, 800);
};
</script>
<style scoped>
.dashboard-layout {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
overflow: hidden;
}
/* 顶部导航样式 */
.layout-header {
height: 60px;
padding: 0 20px;
display: flex;
justify-content: space-between;
align-items: center;
background: url('@/assets/images/dashboard/title_bg.png') center center no-repeat;
background-size: 100% 100%;
border-bottom: 1px solid #334155;
z-index: 10;
}
.layout-title {
font-size: 20px;
font-weight: 600;
color: #f8fafc;
margin: 0;
}
.header-btn {
display: flex;
align-items: center;
gap: 6px;
padding: 6px 12px;
background-color: #334155;
color: #f8fafc;
border: none;
border-radius: 4px;
cursor: pointer;
transition: background-color 0.2s;
}
.header-btn:hover {
background-color: #475569;
}
.header-btn i {
font-size: 16px;
}
/* 图标样式 */
.icon-arrow-left::before {
content: '←';
}
.icon-refresh::before {
content: '↺';
}
.refreshing {
animation: spin 0.8s linear;
}
@keyframes spin {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
/* 图表容器样式 */
.charts-container {
flex: 1;
padding: 20px;
overflow: auto;
box-sizing: border-box;
}
.charts-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-template-rows: repeat(2, 1fr);
gap: 20px;
height: 100%;
}
.chart-item {
background-color: #1e293b;
border-radius: 8px;
padding: 16px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.2);
overflow: hidden;
}
/* 响应式调整 */
@media (max-width: 1200px) {
.charts-grid {
grid-template-columns: 1fr;
grid-template-rows: repeat(4, 1fr);
}
}
</style>