修改自适应
This commit is contained in:
+155
-3
@@ -3,8 +3,8 @@ import CommonAside from '@/components/CommonAside.vue';
|
||||
import CommonHeader from '@/components/CommonHeader.vue';
|
||||
import { useTabsStore } from '@/stores';
|
||||
import { useRouter, useRoute } from 'vue-router';
|
||||
import { ref, watch, reactive, nextTick, onMounted, computed } from 'vue';
|
||||
import { More, Close, CircleClose, ArrowUp } from '@element-plus/icons-vue';
|
||||
import { ref, watch, reactive, nextTick, onMounted, onBeforeUnmount, computed } from 'vue';
|
||||
import { More, Close, CircleClose, ArrowUp, Fold, Expand } from '@element-plus/icons-vue';
|
||||
import { ElMessage } from 'element-plus';
|
||||
|
||||
const tabsStore = useTabsStore();
|
||||
@@ -12,6 +12,44 @@ const router = useRouter();
|
||||
const route = useRoute();
|
||||
const defaultDashboardPath = '/home';
|
||||
|
||||
// ========== 手机端侧栏抽屉控制 ==========
|
||||
const MOBILE_QUERY = '(max-width: 768px)';
|
||||
const mobileMedia = window.matchMedia(MOBILE_QUERY);
|
||||
const isMobile = ref(mobileMedia.matches);
|
||||
// 手机端侧栏默认隐藏,桌面端无影响(CSS 仅在媒体查询内生效)
|
||||
const sidebarVisible = ref(false);
|
||||
|
||||
const handleMobileMediaChange = (e) => {
|
||||
isMobile.value = e.matches;
|
||||
// 切回桌面端时重置侧栏状态,避免残留
|
||||
if (!e.matches) {
|
||||
sidebarVisible.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
// 兼容旧版 Safari 的 addListener 写法
|
||||
if (typeof mobileMedia.addEventListener === 'function') {
|
||||
mobileMedia.addEventListener('change', handleMobileMediaChange);
|
||||
} else {
|
||||
mobileMedia.addListener(handleMobileMediaChange);
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
if (typeof mobileMedia.removeEventListener === 'function') {
|
||||
mobileMedia.removeEventListener('change', handleMobileMediaChange);
|
||||
} else {
|
||||
mobileMedia.removeListener(handleMobileMediaChange);
|
||||
}
|
||||
});
|
||||
|
||||
const toggleMobileSidebar = () => {
|
||||
sidebarVisible.value = !sidebarVisible.value;
|
||||
};
|
||||
|
||||
const closeMobileSidebar = () => {
|
||||
sidebarVisible.value = false;
|
||||
};
|
||||
|
||||
// 根据当前路由恢复 tab(刷新时使用)
|
||||
function restoreTabFromRoute() {
|
||||
const currentPath = route.fullPath;
|
||||
@@ -88,6 +126,10 @@ watch(
|
||||
(newPath) => {
|
||||
if (newPath) {
|
||||
restoreTabFromRoute();
|
||||
// 路由变化时自动关闭手机端侧栏
|
||||
if (isMobile.value) {
|
||||
sidebarVisible.value = false;
|
||||
}
|
||||
}
|
||||
},
|
||||
{ immediate: false }
|
||||
@@ -410,8 +452,33 @@ const canCloseRight = computed(() => {
|
||||
|
||||
<template>
|
||||
<div class="common-layout">
|
||||
<!-- 手机端汉堡菜单按钮(仅 ≤768px 显示,CSS 控制) -->
|
||||
<button
|
||||
class="mobile-menu-btn"
|
||||
:aria-label="sidebarVisible ? '关闭菜单' : '打开菜单'"
|
||||
@click="toggleMobileSidebar"
|
||||
>
|
||||
<el-icon :size="20">
|
||||
<Expand v-if="sidebarVisible" />
|
||||
<Fold v-else />
|
||||
</el-icon>
|
||||
</button>
|
||||
|
||||
<!-- 手机端遮罩层,点击关闭侧栏 -->
|
||||
<transition name="mask-fade">
|
||||
<div
|
||||
v-if="isMobile && sidebarVisible"
|
||||
class="mobile-sidebar-mask"
|
||||
@click="closeMobileSidebar"
|
||||
></div>
|
||||
</transition>
|
||||
|
||||
<el-container class="main-container">
|
||||
<common-aside @menu-click="handleAsideMenuClick" />
|
||||
<common-aside
|
||||
class="common-aside-wrapper"
|
||||
:class="{ 'mobile-open': sidebarVisible }"
|
||||
@menu-click="handleAsideMenuClick"
|
||||
/>
|
||||
<el-container>
|
||||
<el-header class="main-header">
|
||||
<common-header />
|
||||
@@ -666,6 +733,91 @@ const canCloseRight = computed(() => {
|
||||
border-right: none !important;
|
||||
}
|
||||
|
||||
// ========== 手机端侧栏抽屉(仅 ≤768px 生效,桌面端不受影响) ==========
|
||||
// 汉堡按钮:默认隐藏,手机端显示
|
||||
.mobile-menu-btn {
|
||||
display: none;
|
||||
position: fixed;
|
||||
top: 20px;
|
||||
left: 12px;
|
||||
z-index: 2200;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border: none;
|
||||
border-radius: 50%;
|
||||
background: var(--el-color-primary);
|
||||
color: #fff;
|
||||
box-shadow: 0 4px 12px rgba(57, 115, 255, 0.35);
|
||||
cursor: pointer;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
|
||||
&:active {
|
||||
transform: scale(0.92);
|
||||
}
|
||||
}
|
||||
|
||||
// 遮罩层
|
||||
.mobile-sidebar-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
z-index: 2000;
|
||||
background: rgba(0, 0, 0, 0.45);
|
||||
backdrop-filter: blur(2px);
|
||||
}
|
||||
|
||||
.mask-fade-enter-active,
|
||||
.mask-fade-leave-active {
|
||||
transition: opacity 0.3s ease;
|
||||
}
|
||||
|
||||
.mask-fade-enter-from,
|
||||
.mask-fade-leave-to {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.mobile-menu-btn {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
// 覆盖 el-aside 的 :width 内联宽度(200px/64px),改为 fixed 抽屉
|
||||
.common-layout .common-aside-wrapper {
|
||||
position: fixed !important;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 260px !important;
|
||||
max-width: 80vw;
|
||||
height: 100vh;
|
||||
z-index: 2100;
|
||||
transform: translateX(-100%);
|
||||
transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
box-shadow: none;
|
||||
|
||||
&.mobile-open {
|
||||
transform: translateX(0);
|
||||
box-shadow: 4px 0 24px rgba(0, 0, 0, 0.25);
|
||||
}
|
||||
}
|
||||
|
||||
// 内容区不再为侧栏预留空间
|
||||
.main-container {
|
||||
:deep(.el-header),
|
||||
:deep(.el-main) {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
.right-main {
|
||||
padding: 64px 12px 12px;
|
||||
}
|
||||
}
|
||||
|
||||
// 回到顶部按钮样式
|
||||
.backtop-button {
|
||||
width: 40px;
|
||||
|
||||
Reference in New Issue
Block a user