feat(web): 优化前台移动端适配

- 添加响应式 CSS 变量断点系统
- 移动端(<768px):单列布局,汉堡菜单
- 平板(768-1200px):显示副导航
- 桌面(1200px+):完整三栏布局
- 主页网格使用 auto-fill 自适应列数
- 详情页按钮垂直堆叠显示
- 添加移动端抽屉式分类导航
This commit is contained in:
bwstudio
2026-06-10 07:43:59 +08:00
parent 595394fcb7
commit c55d883524
5 changed files with 389 additions and 105 deletions
+153 -4
View File
@@ -3,14 +3,39 @@
<!-- 顶部主导航 -->
<AppHeader
:theme="themeStore.theme"
:menu-open="menuOpen"
@toggleTheme="themeStore.toggleTheme()"
@random="handleRandom"
@toggleMenu="menuOpen = !menuOpen"
/>
<!-- 移动端抽屉菜单 -->
<div class="mobile-drawer" :class="{ open: menuOpen }" @click.self="menuOpen = false">
<div class="drawer-content">
<AppSidebar
:types="allTypes"
:current-type="null"
@selectType="handleDrawerSelectType"
@random="handleRandom"
/>
</div>
</div>
<!-- 内容区域: 左副导航 + 主内容 + 右信息栏 -->
<div class="content-wrapper">
<!-- 左侧副导航内容区内 -->
<!-- 左侧边栏仅大屏幕显示 -->
<div class="left-sidebar">
<AppSidebar
:types="allTypes"
:current-type="null"
@selectType="() => {}"
@random="handleRandom"
/>
</div>
<!-- 左侧副导航平板及以上显示 -->
<AppSubNav
class="left-subnav"
:types="allTypes"
:crowds="allCrowds"
:current-type-ids="filterTypeIds"
@@ -26,8 +51,9 @@
<router-view />
</main>
<!-- 右侧信息栏首页 -->
<!-- 右侧信息栏大屏幕 -->
<AppRightbar
class="rightbar"
v-if="showRightBar"
:hot-jokes="hotJokes"
:types="allTypes"
@@ -55,6 +81,9 @@ const themeStore = useThemeStore()
const route = useRoute()
const router = useRouter()
// 移动端菜单状态
const menuOpen = ref(false)
// 初始化主题
themeStore.initTheme()
@@ -103,6 +132,21 @@ const handleSelectCrowd = (crowdId) => {
filterTypeIds.value = []
const query = ids.length ? { crowd_ids: ids.join(',') } : {}
router.push({ path: '/', query })
// 移动端关闭菜单
menuOpen.value = false
}
// 抽屉菜单选择分类
const handleDrawerSelectType = (typeId) => {
const ids = filterTypeIds.value
const idx = ids.indexOf(typeId)
if (idx >= 0) ids.splice(idx, 1)
else ids.push(typeId)
filterCrowdIds.value = []
const query = ids.length ? { type_ids: ids.join(',') } : {}
router.push({ path: '/', query })
// 移动端关闭菜单
menuOpen.value = false
}
// provide 必须在函数定义之后
@@ -192,6 +236,37 @@ onMounted(async () => {
--tag-crowd-bg: #0a2040;
}
/* ============================================================
响应式断点变量
============================================================ */
:root {
/* 左侧边栏 */
--sidebar-width: 0px;
/* 副导航栏 */
--subnav-width: 220px;
/* 右侧边栏 */
--rightbar-width: 260px;
/* 内容区域最大宽度 */
--content-max-width: 1440px;
/* 顶部导航高度 */
--header-height: 64px;
}
/* 平板(768px+)显示副导航 */
@media (min-width: 768px) {
:root {
--subnav-width: 220px;
}
}
/* 大屏幕(1200px+)显示完整布局 */
@media (min-width: 1200px) {
:root {
--sidebar-width: 220px;
--rightbar-width: 260px;
}
}
/* ============================================================
全局基础样式
============================================================ */
@@ -220,13 +295,40 @@ body {
.content-wrapper {
display: flex;
flex: 1;
max-width: 1440px;
max-width: var(--content-max-width);
margin: 0 auto;
width: 100%;
padding-top: 64px;
padding-top: var(--header-height);
min-height: 100vh;
}
/* 默认隐藏侧边栏,小屏幕适配 */
.left-sidebar { display: none; }
/* 平板及以上显示副导航 */
@media (min-width: 768px) {
.left-subnav {
width: var(--subnav-width);
min-width: var(--subnav-width);
flex-shrink: 0;
}
}
/* 大屏幕显示所有侧边栏 */
@media (min-width: 1200px) {
.left-sidebar {
display: block;
width: var(--sidebar-width);
min-width: var(--sidebar-width);
flex-shrink: 0;
}
.rightbar {
width: var(--rightbar-width);
min-width: var(--rightbar-width);
flex-shrink: 0;
}
}
.main-content {
flex: 1;
min-width: 0;
@@ -254,6 +356,53 @@ body {
.el-button { border-radius: 8px !important; }
.el-pagination.is-background .el-pager li.is-active { background: var(--primary) !important; }
/* ============================================================
移动端抽屉菜单
============================================================ */
.mobile-drawer {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
opacity: 0;
transition: opacity 0.3s;
}
.mobile-drawer.open {
display: block;
opacity: 1;
}
.drawer-content {
position: absolute;
left: 0;
top: 0;
bottom: 0;
width: 280px;
max-width: 80vw;
transform: translateX(-100%);
transition: transform 0.3s;
}
.mobile-drawer.open .drawer-content {
transform: translateX(0);
}
/* 移动端:小屏幕隐藏副导航,显示汉堡菜单按钮 */
@media (max-width: 767px) {
.content-wrapper {
padding-top: var(--header-height);
}
.main-content {
padding: 16px 12px 40px;
}
}
/* ============================================================
深色主题 Element Plus 额外覆盖
============================================================ */