feat(web): 优化前台移动端适配
- 添加响应式 CSS 变量断点系统 - 移动端(<768px):单列布局,汉堡菜单 - 平板(768-1200px):显示副导航 - 桌面(1200px+):完整三栏布局 - 主页网格使用 auto-fill 自适应列数 - 详情页按钮垂直堆叠显示 - 添加移动端抽屉式分类导航
This commit is contained in:
+153
-4
@@ -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 额外覆盖
|
||||
============================================================ */
|
||||
|
||||
Reference in New Issue
Block a user