✨ feat: 数据大屏
This commit is contained in:
165
gear-ui3/src/views/dashboard/layout/index.vue
Normal file
165
gear-ui3/src/views/dashboard/layout/index.vue
Normal file
@@ -0,0 +1,165 @@
|
||||
<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="设置" @click="settingVisible = true">
|
||||
<el-icon><Setting /></el-icon>
|
||||
<span>设置</span>
|
||||
</button>
|
||||
<button
|
||||
class="header-btn refresh-btn"
|
||||
@click="handleRefresh"
|
||||
aria-label="刷新"
|
||||
:disabled="loading"
|
||||
:class="{ refreshing: isRefreshing }"
|
||||
>
|
||||
<el-icon><Refresh /></el-icon>
|
||||
<span>刷新</span>
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<!-- 内容插槽:用于插入图表网格 -->
|
||||
<main class="layout-content" v-loading="loading">
|
||||
<slot></slot>
|
||||
</main>
|
||||
|
||||
<el-dialog v-model="settingVisible" title="图表设置" width="50%">
|
||||
<ChartSetting />
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ArrowLeft, Refresh, Setting } from '@element-plus/icons-vue';
|
||||
import ChartSetting from '../grid/setting.vue';
|
||||
|
||||
// 接收外部传入的状态与方法(props 类型约束)
|
||||
const props = defineProps({
|
||||
title: {
|
||||
type: String,
|
||||
required: true,
|
||||
default: '数据可视化大屏'
|
||||
},
|
||||
loading: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false
|
||||
},
|
||||
isRefreshing: {
|
||||
type: Boolean,
|
||||
required: true,
|
||||
default: false
|
||||
},
|
||||
handleBack: {
|
||||
type: Function,
|
||||
required: true
|
||||
},
|
||||
handleRefresh: {
|
||||
type: Function,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
const settingVisible = ref(false);
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
/* 布局根容器样式 */
|
||||
.dashboard-layout {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
overflow: hidden;
|
||||
background-color: #0f172a; /* 深色背景统一在布局层定义 */
|
||||
}
|
||||
|
||||
/* 顶部导航样式 */
|
||||
.layout-header {
|
||||
height: 60px;
|
||||
padding: 0 20px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
background: linear-gradient(120deg, #1e293b, #0f172a);
|
||||
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: all 0.2s;
|
||||
}
|
||||
|
||||
.header-btn:hover {
|
||||
background-color: #475569;
|
||||
box-shadow: 0 0 8px rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.header-btn:disabled {
|
||||
background-color: #2d3748;
|
||||
cursor: not-allowed;
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
.header-btn i {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* 刷新按钮动画 */
|
||||
.refreshing el-icon {
|
||||
animation: spin 0.8s linear;
|
||||
}
|
||||
|
||||
@keyframes spin {
|
||||
from { transform: rotate(0deg); }
|
||||
to { transform: rotate(360deg); }
|
||||
}
|
||||
|
||||
/* 内容区域容器(插槽父容器) */
|
||||
.layout-content {
|
||||
flex: 1;
|
||||
overflow: hidden; /* 避免与子组件滚动冲突 */
|
||||
}
|
||||
|
||||
/* 小屏幕适配(导航栏) */
|
||||
@media (max-width: 768px) {
|
||||
.layout-title {
|
||||
font-size: 16px;
|
||||
}
|
||||
.header-btn span {
|
||||
display: none; /* 隐藏按钮文字节省空间 */
|
||||
}
|
||||
.header-btn {
|
||||
padding: 6px 8px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user