Vue3+Element Plus侧边菜单动画与移动端覆盖问题求助
解决方案
问题1:修复菜单折叠动画为整体滑出
Element Plus侧边菜单默认动画会触发高度变化,我们通过自定义过渡逻辑,强制菜单仅做宽度方向的平滑滑动:
修改步骤
- 用Vue原生
<Transition>组件包裹<el-aside>,自定义宽度过渡动画 - 给
<el-menu>设置全屏高度和固定定位,避免高度变化触发额外动画 - 直接通过
:collapse属性控制菜单折叠,移除v-if切换aside的逻辑(这是高度异常动画的根源)
核心代码片段
<template> <div class="container-layout"> <el-container> <Transition name="slide"> <el-aside :style="{ width: isCollapsed ? '64px' : '200px' }"> <el-menu class="el-menu-vertical-jt" active-text-color="#ffd04b" background-color="#545c64" text-color="#fff" :default-active="2" @open="handleOpen" @close="handleClose" :collapse="isCollapsed" > <!-- 菜单子项内容保持不变 --> <el-sub-menu index="1"> <template #title><span>Navigator One</span></template> <el-menu-item-group title="Group One"> <el-menu-item index="1-1">item one</el-menu-item> <el-menu-item index="1-2">item two</el-menu-item> </el-menu-item-group> <!-- 其余子项省略 --> </el-sub-menu> </el-menu> </el-aside> </Transition> <!-- 主内容容器 --> <el-container> <el-header> <el-dropdown-menu v-model="isCollapsed"> <el-dropdown-button :label="false">expand</el-dropdown-button> <el-dropdown-button :label="true">collapse</el-dropdown-button> </el-dropdown-menu> </el-header> <el-main>Main</el-main> </el-container> </el-container> </div> </template> <style scoped> /* 自定义滑入滑出过渡 */ .slide-enter-active, .slide-leave-active { transition: width 0.3s ease; } .slide-enter-from, .slide-leave-to { width: 64px !important; } .el-menu-vertical-jt { height: 100vh; position: relative; } .container-layout { width: 100%; height: 100vh; display: flex; } </style>
问题2:小屏幕下默认折叠+覆盖式展开
通过监听屏幕宽度,动态调整菜单定位和主内容布局,实现小屏幕下的覆盖效果:
修改步骤
- 监听窗口大小变化,初始化时判断屏幕宽度,小于768px则默认折叠菜单
- 小屏幕下给菜单设置
fixed定位和高z-index,实现覆盖主内容 - 主内容在大屏幕下随菜单宽度偏移,小屏幕下保持全屏不偏移
核心代码片段
<script setup lang="ts"> import { ref, computed, onMounted, onUnmounted } from 'vue' const isCollapsed = ref(false) const windowWidth = ref(window.innerWidth) // 监听窗口大小变化 const handleResize = () => { windowWidth.value = window.innerWidth // 小屏幕自动折叠 if (windowWidth.value < 768) { isCollapsed.value = true } } onMounted(() => { window.addEventListener('resize', handleResize) // 初始化判断屏幕尺寸 if (windowWidth.value < 768) { isCollapsed.value = true } }) onUnmounted(() => { window.removeEventListener('resize', handleResize) }) // 动态设置菜单样式 const menuStyle = computed(() => { if (windowWidth.value < 768) { return { position: 'fixed', zIndex: 999, left: isCollapsed.value ? '-200px' : '0', height: '100vh' } } return { position: 'relative', height: '100%' } }) // 动态设置主内容样式 const mainContentStyle = computed(() => { if (windowWidth.value >= 768) { return { marginLeft: isCollapsed.value ? '64px' : '200px' } } return {} }) const handleOpen = (key: string, keyPath: string[]) => console.log(key, keyPath) const handleClose = (key: string, keyPath: string[]) => console.log(key, keyPath) </script> <template> <div class="container-layout"> <el-container> <!-- 移除Transition,改用left属性实现侧滑 --> <el-aside style="width: 200px; transition: left 0.3s ease"> <el-menu class="el-menu-vertical-jt" active-text-color="#ffd04b" background-color="#545c64" text-color="#fff" :default-active="2" @open="handleOpen" @close="handleClose" :collapse="isCollapsed" :style="menuStyle" > <!-- 菜单子项内容不变 --> </el-menu> </el-aside> <el-container :style="mainContentStyle"> <!-- 头部和主内容不变 --> </el-container> </el-container> </div> </template>
内容的提问来源于stack exchange,提问作者Dan C
相关产品推荐
相关产品推荐

