使用el-menu做侧边栏导航遇到需要点击两次菜单才展开

在使用Vue和el-menu组件构建侧边栏导航时,遇到一个bug:首次点击菜单不会展开,需要点击两次。问题根源在于`default-active`和`el-submenu`的`index`不匹配,同时使用了`default-openeds`。删除`default-openeds`属性并确保路由`name`设置正确,解决了这个问题。此外,为了避免隐藏路由(如404、login)出现在侧边栏,需要在`sideMenus.vue`中递归处理隐藏路由。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在根据路由遍历生成侧边导航栏时,遇到一个问题,就是当我点击选中某个垂直菜单时,只有点击第二次它才会展开,第一次在选中垂直菜单之后垂直菜单它就收缩起来了,如下图:
在这里插入图片描述
如上图,在我第一次点击选中“告警管理”这个菜单的时候,外联监测它会立马收缩起来,当我第二次点击时就不会收缩,而是展开状态,这是因为我的el-menu里default-active和el-submenu的index及el-menu-item的index属性不一致导致的,default-openeds和default-active尽量不要同时存在,删掉default-openeds即可,路由里name都一定要写上,不然会在控制台报警告,如下截图:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

由于我们这个侧边菜单栏是拿到该角色所拥有的菜单数组集合,那这里

<script lang="ts"> import { ref, onMounted } from 'vue' import { ElMessage, ElMessageBox } from 'element-plus' import { useRouter } from 'vue-router' import request from '@/utils/request' import type { ResultModel } from '@/api/stu' // 定义登录请求数据类型 interface LoginData { username: string password: string } //修改密码 export const updatePasswordApi = (data: LoginData) => request.put<any, ResultModel>('/emps/update', data) //修改员工信息 let router = useRouter() const loginName = ref('') //定义钩子函数, 获取登录用户名 onMounted(() => { //获取登录用户名 const token = localStorage.getItem('token') || '{}' let loginUser = JSON.parse(token) console.log(loginUser) if (loginUser) { loginName.value = loginUser.name } }) const logout = () => { //弹出确认框, 如果确认, 则退出登录, 跳转到登录页面 ElMessageBox.confirm('确认退出登录吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', }).then(() => { //确认, 则清空登录信息 ElMessage.success('退出登录成功') localStorage.removeItem('loginUser') router.push('/login') //跳转到登录页面 }) } </script> <template> <div class="common-layout"> <el-container class="layout-container"> <!-- 头部 --> <el-header class="header"> <span class="title">AI教学管理系统</span> <div class="tools"> <a href=""> <el-icon><EditPen /></el-icon> 修改密码 </a> <a href="javascript:void(0)" @click="logout"> <el-icon><SwitchButton /></el-icon> 退出登录 【{{ loginName }}】 </a> </div> </el-header> <el-container class="main-container"> <!-- 侧边栏 --> <el-aside class="aside"> <!-- 使用 el-scrollbar 包裹菜单 --> <el-scrollbar class="menu-scrollbar"> <el-menu router default-active="1" class="side-menu" background-color="#2c3e50" text-color="#ecf0f1" active-text-color="#f39c12" > <!-- 首页 --> <el-menu-item index="/index"> <el-icon><Menu /></el-icon> <span>首页</span> </el-menu-item> <!-- 班级学员管理子菜单 --> <el-sub-menu index="2" class="menu-group"> <template #title> <el-icon><Document /></el-icon> <span>班级学员管理</span> </template> <el-menu-item index="/stu" ><el-icon><UserFilled /></el-icon>学员管理</el-menu-item > <el-menu-item index="/clazz" ><el-icon><HomeFilled /></el-icon>班级管理</el-menu-item > </el-sub-menu> <!-- 部门员工管理子菜单 --> <el-sub-menu index="3" class="menu-group"> <template #title> <el-icon><Avatar /></el-icon> <span>部门管理</span> </template> <el-menu-item index="/emp" ><el-icon><Avatar /></el-icon>员工管理</el-menu-item > <el-menu-item index="/dept" ><el-icon><HelpFilled /></el-icon>部门管理</el-menu-item > </el-sub-menu> <!-- 新增的统计管理子菜单 --> <el-sub-menu index="4" class="menu-group"> <template #title> <el-icon><PieChart /></el-icon> <span>数据统计管理</span> </template> <el-menu-item index="/report/emp" ><el-icon><InfoFilled /></el-icon>员工信息统计</el-menu-item > <el-menu-item index="/report/stu" ><el-icon><Share /></el-icon>学员信息统计</el-menu-item > <el-menu-item index="/log" ><el-icon><clock /></el-icon>日志信息统计</el-menu-item > </el-sub-menu> </el-menu> </el-scrollbar> </el-aside> <!-- 主内容区 --> <el-main class="main-content"> <router-view></router-view> </el-main> </el-container> </el-container> </div> </template> <style scoped> /* 布局基础样式 */ .common-layout { height: 100vh; display: flex; flex-direction: column; } .layout-container { height: 100%; display: flex; flex-direction: column; } /* 头部样式 */ .header { background-color: #2c3e50; color: white; display: flex; justify-content: space-between; align-items: center; padding: 0 20px; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); z-index: 10; } .title { font-size: 1.5rem; font-weight: bold; } .tools a { color: #ecf0f1; text-decoration: none; margin-left: 20px; display: inline-flex; align-items: center; transition: background-color 0.3s ease; border-radius: 4px; padding: 6px 10px; } .tools a:hover { background-color: #34495e; } /* 侧边栏样式 */ .aside { background-color: #2c3e50; color: #ecf0f1; height: 100%; padding-bottom: 20px; } /* 自定义滚动条样式 */ .menu-scrollbar { height: calc(100vh - 60px); /* 减去 header 高度 */ } .menu-scrollbar .el-scrollbar__bar.is-vertical { width: 6px; right: 2px; border-radius: 4px; background-color: rgba(255, 255, 255, 0.1); } .menu-scrollbar .el-scrollbar__thumb { background-color: rgba(255, 255, 255, 0.3); border-radius: 4px; transition: background-color 0.3s ease; } .menu-scrollbar .el-scrollbar__thumb:hover { background-color: rgba(255, 255, 255, 0.5); } /* 菜单样式 */ .side-menu { background-color: transparent; border-right: none; padding: 10px 0; } /* 菜单项通用样式 */ .side-menu .el-menu-item, .side-menu .el-sub-menu .el-sub-menu__title { margin: 6px 0; padding: 10px 20px; font-size: 14px; color: #ecf0f1; border-radius: 6px; transition: all 0.3s ease; } /* 悬停样式 */ .side-menu .el-menu-item:hover, .side-menu .el-sub-menu .el-sub-menu__title:hover { background-color: #34495e; } /* 激活项样式 */ .side-menu .el-menu-item.is-active { background-color: #34495e; color: #f39c12 !important; font-weight: bold; } /* 子菜单项样式 */ .menu-group .el-menu-item { font-size: 13px; padding-left: 40px !important; color: #dcdcdc; transition: all 0.3s ease; } .menu-group .el-menu-item:hover { background-color: #3a5267; } .menu-group .el-menu-item.is-active { background-color: #3a5267; color: #f1c40f; } /* 主内容区样式 */ .main-content { background-color: #f9f9f9; padding: 20px; flex: 1; overflow-y: auto; } /* 响应式设计 */ @media (max-width: 768px) { .tools a { margin-left: 10px; font-size: 0.9rem; padding: 4px 8px; } .title { font-size: 1.2rem; } .menu-group .el-menu-item { font-size: 12px; padding-left: 25px !important; } } </style> 优化一下代码逻辑,以及头部效果 ,有个修改密码的api完善一下修改密码功能
07-24
为什么我更改 权限 手机号 单位 过后不会在列表显示 <div class="common-layout"> <el-container> <el-header> <div class="header-content"> <h1>仓库管理系统</h1> <div class="user-info"> <span>欢迎, {{ loginInfor.usernames }}</span> </div> </div> </el-header> <el-container> <el-aside width="200px"> <el-menu default-active="dashboard" class="sidebar-menu" model="vertical" background-color="#00BFFF" text-color="#ffffff" active-text-color="#ffffff" @select="handleMenuSelect"> <div class="demo-collapse"> <el-collapse v-model="activeNames" @change="handleChange"> <el-collapse-item title="仓库管理" name="1"> <div class="el-icon-download"> <el-menu-item @click="createNewContent" index="inbound">新型装备入库</el-menu-item> </div> <div> <el-menu-item index="inbound" @click="showDatainfor=true,showCKSPinfor=false,showbel=false">查询装备信息</el-menu-item> </div> <div> <el-menu-item index="inbound" @click="showDatainfor=false,showCKSPinfor=true,showbel=false">出库申请单审批</el-menu-item> </div> <div><el-menu-item index="inbound" @click="showDatainfor=false,showCKSPinfor=false,showbel=true">用户管理</el-menu-item></div> </el-collapse-item> </el-collapse> <el-menu-item index="inbound">报表统计</el-menu-item> <el-menu-item index="inbound">系统设置</el-menu-item> </div> </el-menu> </el-aside> <el-main> <div v-if="showDatainfor"><maindata /></div> <div v-if="showCKSPinfor"><CkCheck/></div> <div v-if="showbel"><Usertable/></div> </el-main> </el-container> </el-container> </div> <!-- 增加新装备弹窗 --> <el-dialog v-model="newuser" title="增加新装备" :center="true" width="30%"> <div class="newcountClass"> <el-form ref="registerFormRef" :model="newzhuangbei" :rules="rules" label-width="90px" class="register-form" > <el-form-item label="条形码/二维码" prop="qrcode"> <el-input v-model="newzhuangbei.qrcode" placeholder="请输入条形码/二维码" ></el-input> </el-form-item> <el-form-item label="名称" prop="totalname"> <el-input v-model="newzhuangbei.totalname" placeholder="请输入名称" ></el-input> </el-form-item> <el-form-item label="品牌" prop="brand" > <el-input v-model="newzhuangbei.brand" placeholder="请输入品牌" ></el-input> </el-form-item> <el-form-item label="型号" prop="model" > <el-input v-model="newzhuangbei.model" placeholder="请输入型号" ></el-input> </el-form-item> <el-form-item label="装备识别码" prop="equipmentcode" > <el-input v-model="newzhuangbei.equipmentcode" placeholder="请输入装备识别码" ></el-input> </el-form-item> <el-form-item label="所属单位" prop="roomlocation" > <el-input v-model="newzhuangbei.roomlocation" placeholder="请输入单位信息" ></el-input> </el-form-item> <el-form-item label="入库数量" prop="kcnum" > <el-input-number v-model="newzhuangbei.kcnum" :min="1" :max="10" @change="handleChange" /> </el-form-item> <el-form-item label="备注" prop="remark" > <el-input v-model="newzhuangbei.remark" placeholder="请输入备注信息" ></el-input> </el-form-item> <el-form-item label="登录时间" prop="totaldate" > <el-input v-model="newzhuangbei.totaldate" placeholder="请输入登录时间" ></el-input> </el-form-item> <el-form-item label="登录人员" prop="totaluser" > <el-input v-model="newzhuangbei.totaluser" placeholder="请输入登录人员" ></el-input> </el-form-item> <div class="button-container"> <el-button type="primary" @click="creatuserhandler" class="large-button" >新增成功</el-button> </div> </el-form> </div> </el-dialog> </template> <script setup> import { onMounted,reactive,ref } from 'vue'; import { dataUser } from "../Util/apirequest/test.js"; import { ElMessage } from "element-plus"; import maindata from "./maindata.vue"; import CkCheck from './ckCheck.vue'; import Usertable from './usertable.vue'; const showDatainfor=ref(true); const showCKSPinfor=ref(false); const showbel=ref(false); const newuser=ref(false) const loginInfor=reactive({ usernames:'', permits:'' }); onMounted(()=>{ // 默认进入页面执行 loginInfor.usernames = localStorage.getItem('loginInfor'); loginInfor.permits = localStorage.getItem('permit') }); function createNewContent() { if(loginInfor.permits==='\"超级管理员\"'){ newuser.value=true; } else{ ElMessage.error("权限不足"); } } const newzhuangbei=reactive({ qrcode:'',//二维码或条形码 totalname:'',//名称 brand:'',// model:'', equipmentcode:'', roomlocation:'', kcnum:',', remark:'', totaldate:'', totaluser:'', }); function creatuserhandler(){ dataUser(newzhuangbei).then((res) => { if(res.trim()=="error:二维码/条形码已存在!") { ElMessage.error("二维码/条形码已被使用!"); } else if(res.trim()=="true") { ElMessage.success("装备入库成功!"); newuser.value = false; // console.log('装备入库成功!'); } else { console.log(res); } }); } </script> <style lang='scss' scoped> /* 主内容区域样式已整合到el-main中 */ // 侧边栏样式 .sidebar { width: 200px; background-color: #43dad0; height: 100%; transition: all 0.3s; box-shadow: 2px 0 8px #1c929b; /* 右侧阴影 */ } .sidebar-menu { height: 100%; border-right: none; padding-top: 0px; /* 顶部留白 */ .el-submenu__title, .el-menu-item { height: 50px; line-height: 50px; font-size: 14px; padding-left: 24px !important; /* 增加左内边距 */ transition: all 0.2s; } // 图标样式统一 .el-submenu__title i, .el-menu-item i { width: 20px; text-align: center; margin-right: 10px; font-size: 16px; } // 选中状态优化 .el-menu-item.is-active { background-color: #11dcd8 !important; border-left: 3px solid #4bfff0; /* 左侧高亮条 */ } // hover效果 .el-submenu__title:hover, .el-menu-item:hover { background-color: rgba(71, 214, 230, 0.1) !important; } // 子菜单样式 .el-submenu .el-menu { background-color: #2b7fd8;/* 子菜单深色背景 */ } .el-submenu .el-menu-item { padding-left: 44px !important; /* 子菜单缩进 */ } } // 页面内容区域 .page-content { flex: 1; padding: 20px; overflow-y: auto; background-color: #f5f7fa; transition: all 0.3s; } </style><template> <div class="common-layout"> <el-container> <el-header> <div class="header-content"> <h1>仓库管理系统</h1> <div class="user-info"> <span>欢迎, {{ loginInfor.usernames }}</span> </div> </div> </el-header> <el-container> <el-aside width="200px"> <el-menu default-active="dashboard" class="sidebar-menu" model="vertical" background-color="#00BFFF" text-color="#ffffff" active-text-color="#ffffff" @select="handleMenuSelect"> <div class="demo-collapse"> <el-collapse v-model="activeNames" @change="handleChange"> <el-collapse-item title="仓库管理" name="1"> <div class="el-icon-download"> <el-menu-item @click="createNewContent" index="inbound">新型装备入库</el-menu-item> </div> <div> <el-menu-item index="inbound" @click="showDatainfor=true,showCKSPinfor=false,showbel=false">查询装备信息</el-menu-item> </div> <div> <el-menu-item index="inbound" @click="showDatainfor=false,showCKSPinfor=true,showbel=false">出库申请单审批</el-menu-item> </div> <div><el-menu-item index="inbound" @click="showDatainfor=false,showCKSPinfor=false,showbel=true">用户管理</el-menu-item></div> </el-collapse-item> </el-collapse> <el-menu-item index="inbound">报表统计</el-menu-item> <el-menu-item index="inbound">系统设置</el-menu-item> </div> </el-menu> </el-aside> <el-main> <div v-if="showDatainfor"><maindata /></div> <div v-if="showCKSPinfor"><CkCheck/></div> <div v-if="showbel"><Usertable/></div> </el-main> </el-container> </el-container> </div> <!-- 增加新装备弹窗 --> <el-dialog v-model="newuser" title="增加新装备" :center="true" width="30%"> <div class="newcountClass"> <el-form ref="registerFormRef" :model="newzhuangbei" :rules="rules" label-width="90px" class="register-form" > <el-form-item label="条形码/二维码" prop="qrcode"> <el-input v-model="newzhuangbei.qrcode" placeholder="请输入条形码/二维码" ></el-input> </el-form-item> <el-form-item label="名称" prop="totalname"> <el-input v-model="newzhuangbei.totalname" placeholder="请输入名称" ></el-input> </el-form-item> <el-form-item label="品牌" prop="brand" > <el-input v-model="newzhuangbei.brand" placeholder="请输入品牌" ></el-input> </el-form-item> <el-form-item label="型号" prop="model" > <el-input v-model="newzhuangbei.model" placeholder="请输入型号" ></el-input> </el-form-item> <el-form-item label="装备识别码" prop="equipmentcode" > <el-input v-model="newzhuangbei.equipmentcode" placeholder="请输入装备识别码" ></el-input> </el-form-item> <el-form-item label="所属单位" prop="roomlocation" > <el-input v-model="newzhuangbei.roomlocation" placeholder="请输入单位信息" ></el-input> </el-form-item> <el-form-item label="入库数量" prop="kcnum" > <el-input-number v-model="newzhuangbei.kcnum" :min="1" :max="10" @change="handleChange" /> </el-form-item> <el-form-item label="备注" prop="remark" > <el-input v-model="newzhuangbei.remark" placeholder="请输入备注信息" ></el-input> </el-form-item> <el-form-item label="登录时间" prop="totaldate" > <el-input v-model="newzhuangbei.totaldate" placeholder="请输入登录时间" ></el-input> </el-form-item> <el-form-item label="登录人员" prop="totaluser" > <el-input v-model="newzhuangbei.totaluser" placeholder="请输入登录人员" ></el-input> </el-form-item> <div class="button-container"> <el-button type="primary" @click="creatuserhandler" class="large-button" >新增成功</el-button> </div> </el-form> </div> </el-dialog> </template> <script setup> import { onMounted,reactive,ref } from 'vue'; import { dataUser } from "../Util/apirequest/test.js"; import { ElMessage } from "element-plus"; import maindata from "./maindata.vue"; import CkCheck from './ckCheck.vue'; import Usertable from './usertable.vue'; const showDatainfor=ref(true); const showCKSPinfor=ref(false); const showbel=ref(false); const newuser=ref(false) const loginInfor=reactive({ usernames:'', permits:'' }); onMounted(()=>{ // 默认进入页面执行 loginInfor.usernames = localStorage.getItem('loginInfor'); loginInfor.permits = localStorage.getItem('permit') }); function createNewContent() { if(loginInfor.permits==='\"超级管理员\"'){ newuser.value=true; } else{ ElMessage.error("权限不足"); } } const newzhuangbei=reactive({ qrcode:'',//二维码或条形码 totalname:'',//名称 brand:'',// model:'', equipmentcode:'', roomlocation:'', kcnum:',', remark:'', totaldate:'', totaluser:'', }); function creatuserhandler(){ dataUser(newzhuangbei).then((res) => { if(res.trim()=="error:二维码/条形码已存在!") { ElMessage.error("二维码/条形码已被使用!"); } else if(res.trim()=="true") { ElMessage.success("装备入库成功!"); newuser.value = false; // console.log('装备入库成功!'); } else { console.log(res); } }); } </script> <style lang='scss' scoped> /* 主内容区域样式已整合到el-main中 */ // 侧边栏样式 .sidebar { width: 200px; background-color: #43dad0; height: 100%; transition: all 0.3s; box-shadow: 2px 0 8px #1c929b; /* 右侧阴影 */ } .sidebar-menu { height: 100%; border-right: none; padding-top: 0px; /* 顶部留白 */ .el-submenu__title, .el-menu-item { height: 50px; line-height: 50px; font-size: 14px; padding-left: 24px !important; /* 增加左内边距 */ transition: all 0.2s; } // 图标样式统一 .el-submenu__title i, .el-menu-item i { width: 20px; text-align: center; margin-right: 10px; font-size: 16px; } // 选中状态优化 .el-menu-item.is-active { background-color: #11dcd8 !important; border-left: 3px solid #4bfff0; /* 左侧高亮条 */ } // hover效果 .el-submenu__title:hover, .el-menu-item:hover { background-color: rgba(71, 214, 230, 0.1) !important; } // 子菜单样式 .el-submenu .el-menu { background-color: #2b7fd8;/* 子菜单深色背景 */ } .el-submenu .el-menu-item { padding-left: 44px !important; /* 子菜单缩进 */ } } // 页面内容区域 .page-content { flex: 1; padding: 20px; overflow-y: auto; background-color: #f5f7fa; transition: all 0.3s; } </style>
最新发布
08-27
<script lang="ts" setup> import { ref, onMounted, nextTick } from 'vue' import { ElMessage, ElMessageBox, type FormInstance, type FormRules } from 'element-plus' import { useRouter } from 'vue-router' import request from '@/utils/request' import type { ResultModel } from '@/api/model/model' // 类型定义 interface PasswordForm { oldPassword: string newPassword: string confirmPassword: string } interface LoginUser { id: number username: string // 增加用户名字段 name: string role: string } // API调用(修改参数结构) const updatePasswordApi = (data: { username: string; password: string; newPassword: string }) => request.put<any, ResultModel>('/emps/update', data) const router = useRouter() const loginName = ref('管理员') const loginRole = ref('管理员') const username = ref('') // 存储用户名 const showPasswordDialog = ref(false) const passwordForm = ref<PasswordForm>({ oldPassword: '', newPassword: '', confirmPassword: '', }) const passwordFormRef = ref<FormInstance>() const loading = ref(false) // 密码验证规则 const passwordRules: FormRules<PasswordForm> = { oldPassword: [ { required: true, message: '请输入旧密码', trigger: 'blur' }, { min: 6, max: 20, message: '密码长度6-20个字符', trigger: 'blur' }, ], newPassword: [ { required: true, message: '请输入新密码', trigger: 'blur' }, { min: 6, max: 20, message: '密码长度6-20个字符', trigger: 'blur' }, { validator: (_, value, callback) => { if (value === passwordForm.value.oldPassword) { callback(new Error('新密码不能与旧密码相同')) } else { callback() } }, trigger: 'blur', }, ], confirmPassword: [ { required: true, message: '请确认新密码', trigger: 'blur' }, { validator: (_, value, callback) => { if (value !== passwordForm.value.newPassword) { callback(new Error('两次输入的密码不一致')) } else { callback() } }, trigger: 'blur', }, ], } // 初始化用户信息(增加用户名获取) onMounted(() => { const token = localStorage.getItem('token') if (token) { try { const loginUser: LoginUser = JSON.parse(token) loginName.value = loginUser.name || '管理员' loginRole.value = loginUser.role || '管理员' username.value = loginUser.username || '' // 获取用户名 } catch (e) { console.error('解析token失败:', e) } } }) // 打开修改密码对话框(保持不变) const openPasswordDialog = () => { showPasswordDialog.value = true passwordForm.value = { oldPassword: '', newPassword: '', confirmPassword: '' } nextTick(() => { if (passwordFormRef.value) { passwordFormRef.value.resetFields() } }) } // 提交修改密码(调整跳转逻辑) const submitPassword = async () => { if (!passwordFormRef.value) return try { await passwordFormRef.value.validate() loading.value = true const response = await updatePasswordApi({ username: username.value, password: passwordForm.value.oldPassword, newPassword: passwordForm.value.newPassword, }) if (response.code === 1) { ElMessage.success('密码修改成功,请重新登录') showPasswordDialog.value = false passwordFormRef.value.resetFields() // 直接跳转到登录页面,不显示退出确认 localStorage.removeItem('token') router.push('/login') } else { ElMessage.error(response.msg || '密码修改失败') } } catch (error) { console.error('修改密码失败:', error) ElMessage.error('请求失败,请稍后重试') } finally { loading.value = false } } // 修改退出登录方法(保持原有的确认提示) const logout = () => { ElMessageBox.confirm('确定要退出登录吗?', '提示', { confirmButtonText: '确定', cancelButtonText: '取消', type: 'warning', center: true, }) .then(() => { localStorage.removeItem('token') router.push('/login') ElMessage.success('退出登录成功') }) .catch(() => {}) } </script> <template> <div class="common-layout"> <el-container class="layout-container"> <!-- 优化后的头部 --> <el-header class="header"> <div class="header-content"> <div class="logo-section"> <div class="logo"></div> <span class="title">AI教学管理系统</span> </div> <div class="user-section"> <div class="user-info"> <el-avatar class="user-avatar" :size="36"> {{ loginName.charAt(0) }} </el-avatar> <div class="user-details"> <div class="user-name">{{ loginName }}</div> <div class="user-role">{{ loginRole }}</div> </div> </div> <div class="header-tools"> <el-tooltip content="修改密码" placement="bottom"> <el-button class="tool-btn" type="text" @click="openPasswordDialog"> <el-icon class="icon"><EditPen /></el-icon> </el-button> </el-tooltip> <el-tooltip content="退出登录" placement="bottom"> <el-button class="tool-btn" type="text" @click="logout"> <el-icon class="icon"><SwitchButton /></el-icon> </el-button> </el-tooltip> </div> </div> </div> </el-header> <el-container class="main-container"> <!-- 侧边栏 --> <el-aside class="aside"> <el-scrollbar class="menu-scrollbar"> <el-menu router default-active="/index" class="side-menu" background-color="#2c3e50" text-color="#ecf0f1" active-text-color="#f39c12" > <el-menu-item index="/index"> <el-icon><Menu /></el-icon> <span>首页</span> </el-menu-item> <el-sub-menu index="2" class="menu-group"> <template #title> <el-icon><Document /></el-icon> <span>班级学员管理</span> </template> <el-menu-item index="/stu"> <el-icon><UserFilled /></el-icon> <span>学员管理</span> </el-menu-item> <el-menu-item index="/clazz"> <el-icon><HomeFilled /></el-icon> <span>班级管理</span> </el-menu-item> </el-sub-menu> <el-sub-menu index="3" class="menu-group"> <template #title> <el-icon><Avatar /></el-icon> <span>部门管理</span> </template> <el-menu-item index="/emp"> <el-icon><Avatar /></el-icon> <span>员工管理</span> </el-menu-item> <el-menu-item index="/dept"> <el-icon><HelpFilled /></el-icon> <span>部门管理</span> </el-menu-item> </el-sub-menu> <el-sub-menu index="4" class="menu-group"> <template #title> <el-icon><PieChart /></el-icon> <span>数据统计管理</span> </template> <el-menu-item index="/report/emp"> <el-icon><InfoFilled /></el-icon> <span>员工信息统计</span> </el-menu-item> <el-menu-item index="/report/stu"> <el-icon><Share /></el-icon> <span>学员信息统计</span> </el-menu-item> <el-menu-item index="/log"> <el-icon><Clock /></el-icon> <span>日志信息统计</span> </el-menu-item> </el-sub-menu> </el-menu> </el-scrollbar> </el-aside> <!-- 主内容区 --> <el-main class="main-content"> <router-view></router-view> </el-main> </el-container> </el-container> <!-- 修改密码对话框 --> <el-dialog v-model="showPasswordDialog" title="修改密码" width="500px" center :close-on-click-modal="false" > <el-form ref="passwordFormRef" :model="passwordForm" :rules="passwordRules" label-width="100px" label-position="right" > <el-form-item label="旧密码" prop="oldPassword"> <el-input v-model="passwordForm.oldPassword" type="password" placeholder="请输入当前密码" show-password clearable /> </el-form-item> <el-form-item label="新密码" prop="newPassword"> <el-input v-model="passwordForm.newPassword" type="password" placeholder="6-20位字符" show-password clearable /> </el-form-item> <el-form-item label="确认密码" prop="confirmPassword"> <el-input v-model="passwordForm.confirmPassword" type="password" placeholder="请再次输入新密码" show-password clearable /> </el-form-item> </el-form> <template #footer> <div class="dialog-footer"> <el-button @click="showPasswordDialog = false">取消</el-button> <el-button type="primary" @click="submitPassword" :loading="loading"> 确认修改 </el-button> </div> </template> </el-dialog> </div> </template> <style scoped> /* 布局基础样式 */ .common-layout { height: 100vh; display: flex; flex-direction: column; background-color: #f5f7fa; } .layout-container { height: 100%; display: flex; flex-direction: column; } /* 头部样式 - 优化版 */ .header { background: linear-gradient(135deg, #2c3e50 0%, #1a2530 100%); color: white; height: 64px; padding: 0; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); z-index: 1000; position: relative; } .header-content { display: flex; justify-content: space-between; align-items: center; height: 100%; padding: 0 30px; max-width: 1600px; margin: 0 auto; width: 100%; } .logo-section { display: flex; align-items: center; gap: 15px; } .logo { width: 40px; height: 40px; background: linear-gradient(135deg, #3498db, #8e44ad); border-radius: 8px; display: flex; align-items: center; justify-content: center; color: white; font-weight: bold; box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2); } .title { font-size: 1.8rem; font-weight: 700; letter-spacing: 1px; background: linear-gradient(to right, #f39c12, #f1c40f); -webkit-background-clip: text; background-clip: text; -webkit-text-fill-color: transparent; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .user-section { display: flex; align-items: center; gap: 20px; } .user-info { display: flex; align-items: center; gap: 12px; padding: 5px 15px; border-radius: 30px; background: rgba(255, 255, 255, 0.1); transition: all 0.3s ease; } .user-info:hover { background: rgba(255, 255, 255, 0.15); } .user-avatar { background: linear-gradient(135deg, #3498db, #8e44ad); display: flex; align-items: center; justify-content: center; font-weight: bold; color: white; box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); } .user-details { display: flex; flex-direction: column; } .user-name { font-weight: 600; font-size: 15px; letter-spacing: 0.5px; } .user-role { font-size: 12px; color: #bdc3c7; margin-top: 2px; } .header-tools { display: flex; gap: 8px; } .tool-btn { color: #ecf0f1; font-size: 18px; padding: 8px; transition: all 0.3s ease; border-radius: 50%; width: 40px; height: 40px; display: flex; align-items: center; justify-content: center; } .tool-btn:hover { background-color: rgba(255, 255, 255, 0.15); transform: translateY(-2px); } .tool-btn .icon { transition: transform 0.3s ease; } .tool-btn:hover .icon { transform: scale(1.2); } /* 侧边栏样式 */ .aside { background-color: #2c3e50; color: #ecf0f1; height: 100%; width: 240px !important; transition: width 0.3s ease; border-right: 1px solid #34495e; } .menu-scrollbar { height: calc(100vh - 64px); } .menu-scrollbar .el-scrollbar__bar.is-vertical { width: 6px; right: 2px; border-radius: 4px; background-color: rgba(255, 255, 255, 0.1); } .menu-scrollbar .el-scrollbar__thumb { background-color: rgba(255, 255, 255, 0.3); border-radius: 4px; transition: background-color 0.3s ease; } .menu-scrollbar .el-scrollbar__thumb:hover { background-color: rgba(255, 255, 255, 0.5); } .side-menu { background-color: transparent; border-right: none; padding: 15px 0; } .side-menu .el-menu-item, .side-menu .el-sub-menu .el-sub-menu__title { margin: 6px 10px; padding: 12px 20px; font-size: 14px; color: #ecf0f1; border-radius: 6px; transition: all 0.3s ease; height: 48px; display: flex; align-items: center; } .side-menu .el-menu-item:hover, .side-menu .el-sub-menu .el-sub-menu__title:hover { background-color: #34495e; transform: translateX(5px); } .side-menu .el-menu-item.is-active { background: linear-gradient(90deg, rgba(52, 152, 219, 0.3), transparent); color: #f39c12 !important; font-weight: bold; border-left: 3px solid #f39c12; } .menu-group .el-menu-item { font-size: 13px; padding-left: 50px !important; color: #dcdcdc; transition: all 0.3s ease; height: 42px; } .menu-group .el-menu-item:hover { background-color: #3a5267; transform: translateX(5px); } .menu-group .el-menu-item.is-active { background-color: #3a5267; color: #f1c40f; font-weight: 600; } /* 主内容区样式 */ .main-content { background-color: #f0f2f5; padding: 20px; flex: 1; overflow-y: auto; border-radius: 8px 8px 0 0; box-shadow: inset 0 2px 8px rgba(0, 0, 0, 0.05); } /* 对话框样式 */ .dialog-footer { display: flex; justify-content: center; padding: 10px 20px 0; } /* 响应式设计 */ @media (max-width: 992px) { .aside { width: 200px !important; } .header-content { padding: 0 20px; } .title { font-size: 1.5rem; } .user-info .user-name { display: none; } } @media (max-width: 768px) { .aside { width: 64px !important; } .logo-section .title, .user-info .user-details, .el-sub-menu .el-sub-menu__title span, .el-menu-item span { display: none; } .el-sub-menu .el-sub-menu__title, .el-menu-item { justify-content: center; padding: 0 !important; } .el-icon { margin-right: 0 !important; font-size: 20px; } .menu-group .el-menu-item { padding-left: 20px !important; justify-content: flex-start; } } </style> 优化一下页面自适应大小,页面缩小之后右上角的退出登录会被挡住
07-24
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值