Siderbar和Navbar

当然可以!我们一起来逐行分析 你提供的这段 Vue 组件代码。这段代码是一个 CMS 系统的侧边栏(Sidebar)组件,它的主要作用是:

根据路由配置动态渲染出左侧菜单栏,并支持点击跳转、高亮当前页面等功能。


🧩 一、整体结构概览

vue 复制代码
<template>
  <div class="has-logo">
    <!-- 系统标题 + Logo -->
    <p @click="goHome" class="system-title">...</p>

    <!-- 菜单容器 -->
    <el-menu ...>
      <sidebar-item v-for="route in permission_routes" ... />
    </el-menu>
  </div>
</template>
  • 使用了 Element UI 的 el-menu 组件来构建菜单。
  • 菜单项由 递归组件 SidebarItem 渲染(你之前问过这个组件)。
  • 菜单数据来自 permission_routes(本例中是写死的,实际项目中通常来自 Vuex 或 API)。

vue 复制代码
<p @click="goHome" class="system-title">
  <img src="../../assets/logo.png" alt="">
  CMS页面配置系统
</p>

✅ 作用:

  • 显示系统 Logo 和名称。
  • 点击后跳转到首页(/home)。

💡 为什么这样写?

  • <p> 而不是 <div>:语义上更合适(段落标题)。
  • @click="goHome":实现"点击 Logo 回首页"的常见交互。
  • 图片路径是相对路径 ../../assets/logo.png,符合 Vue CLI 项目结构。

📋 三、菜单主体:<el-menu>

vue 复制代码
<el-menu
  :default-active="activeMenu"
  :collapse="true"
  background-color="#304156"
  text-color="#bfcbd9"
  :unique-opened="true"
  active-text-color="#409EFF"
  :collapse-transition="false"
  mode="vertical"
>

🔧 属性解释:

属性 作用
:default-active="activeMenu" 高亮当前菜单项 。值是当前路由路径(如 /decorate
:collapse="true" 菜单始终折叠(不显示文字,只显示图标)。但注意:你没传图标,所以可能只显示空白?
background-color / text-color 自定义菜单样式,符合后台系统风格
:unique-opened="true" 只允许一个子菜单展开(避免多个展开太乱)
active-text-color 当前激活项的文字颜色(蓝色)
:collapse-transition="false" 关闭折叠动画,提升性能或避免闪烁
mode="vertical" 垂直菜单(默认,可省略)

⚠️ 注意:你这里写死了 :collapse="true",意味着菜单永远是收起状态。通常这个值应该来自 Vuex(比如用户点击汉堡按钮切换),但你注释掉了相关逻辑。


🔁 四、动态渲染菜单项

vue 复制代码
<sidebar-item
  v-for="route in permission_routes"
  :key="route.path"
  :item="route"
  :base-path="route.path"
/>

✅ 作用:

  • 遍历 permission_routes 数组,为每个路由生成一个菜单项。
  • 把当前路由对象 route 传给 SidebarItem 组件(就是你之前问的那个组件)。
  • :base-path="route.path":用于拼接子路由的完整路径。

💡 为什么用 v-for + 递归组件?

  • 因为菜单是树形结构(可能有多级嵌套),用递归组件最简洁。
  • SidebarItem 内部会判断:是显示为"单个按钮"还是"可展开子菜单"。

📦 五、permission_routes 数据结构分析

你写死了一个很长的路由数组。我们简化来看几个关键项:

js 复制代码
[
  {
    path: '/',
    redirect: '/home',
    children: [
      { path: '/home', meta: { title: '首页' }, hidden: true },
      { path: '/editPassword', meta: { title: '修改密码' }, hidden: true }
    ]
  },
  {
    path: '/decorate',
    name: 'decorate'
    // 没有 meta.title?可能不会显示在菜单!
  },
  {
    path: '/activity',
    meta: { title: '活动管理' },
    children: [{ path: '/', hidden: true }]
  },
  {
    path: '/noRedirect0',
    name: '活动管理',
    meta: { title: '活动管理', icon: '' },
    children: [] // 没有子菜单
  }
]

🔍 关键规则(由 SidebarItem 决定):

  1. 只有包含 meta.title 的路由才会显示在菜单中
    • /decorate 没有 meta,所以不会显示
  2. hidden: true 的路由不会显示(如首页、修改密码通常不需要在菜单展示)。
  3. children 且未被隐藏 → 显示为子菜单
  4. 没有 children → 显示为普通菜单项

✅ 所以最终菜单可能只显示:

  • "活动管理"(来自 /noRedirect0/activity

🎯 六、计算属性 activeMenu

js 复制代码
computed: {
  activeMenu() {
    const route = this.$route
    const { meta, path } = route
    if (meta.activeMenu) {
      return meta.activeMenu // 特殊情况:手动指定高亮菜单
    }
    return path // 默认:高亮当前路径
  }
}

✅ 作用:

  • 控制 el-menudefault-active,实现当前页面菜单高亮
  • 支持特殊场景:比如某个页面想高亮父菜单(如"用户列表"页面高亮"用户管理")。

💡 举例:

  • 当前访问 /decorateactiveMenu = '/decorate' → 菜单中 /decorate 项高亮。
  • 如果路由配置了 meta: { activeMenu: '/user' },即使当前路径是 /user/list,也会高亮 /user

🏠 七、方法 goHome

js 复制代码
methods: {
  goHome() {
    this.$router.push('/home')
  }
}
  • 点击 Logo 跳转到首页。
  • 使用 Vue Router 的编程式导航。

🎨 八、样式部分

less 复制代码
.system-title {
  cursor: pointer;
  display: flex;
  justify-content: center;
  align-items: center;
  padding: 10px 0;
  font-size: 16px;
  color: #fff;
  img {
    margin-right: 5px;
    width: 50px;
    height: 50px;
  }
}
  • 居中 Logo 和文字。
  • 鼠标悬停有手型光标(cursor: pointer)。
  • 白色文字(适配深色背景)。

🚨 九、潜在问题 & 改进建议

1. 菜单项缺失 meta.title

  • /decorate 没有 meta.title,所以不会显示。
  • 修复 :加上 meta: { title: '装修页面' }

2. 菜单始终折叠(:collapse="true"

  • 用户无法看到菜单文字,体验差。

  • 修复 :改成响应式,比如:

    js 复制代码
    :collapse="!sidebar.opened"

    并恢复被注释的 mapGettersisCollapse

3. permission_routes 应该从 Vuex 获取

  • 现在是写死的,不利于权限控制。

  • 修复 :取消注释:

    js 复制代码
    ...mapGetters({
      permission_routes: 'permission/permission_routes',
      sidebar: 'app/sidebar'
    })

4. /activity 的 children 是 [{ path: '/', hidden: true }]

  • 这会导致 SidebarItem 认为它"没有可见子菜单",于是显示父菜单自己。
  • 但父菜单的 component 是 layout,可能无法直接访问。
  • 建议 :要么给子菜单加 meta.title,要么去掉 children

✅ 总结:这段代码的作用

部分 功能
Logo 区域 显示系统名称,点击回首页
el-menu 渲染菜单容器,控制样式和交互
v-for + SidebarItem 动态生成多级菜单(递归)
activeMenu 高亮当前页面对应的菜单项
permission_routes 菜单数据源(应来自权限系统)

如果你想,我可以帮你:

  1. 修复菜单不显示的问题 (补全 meta.title)。
  2. 恢复侧边栏展开/收起功能
  3. 连接 Vuex 获取真实路由

需要的话,告诉我你想先改哪部分 😊

相关推荐
银安3 小时前
初识前端工程化
前端
银安3 小时前
前端工程化的发展——2012 前后 Grunt / Gulp 任务流
前端
鹏多多3 小时前
React跨组件数据共享useContext详解和案例
前端·javascript·react.js
linux kernel3 小时前
第一部分:HTML
前端·html
excel4 小时前
基于两台服务器的蓝绿切换实现零下线更新
前端
江城开朗的豌豆4 小时前
React生命周期:从诞生到更新的完整旅程
前端·javascript·react.js
江城开朗的豌豆4 小时前
Redux vs Context+Hooks:前端状态管理的双雄对决
前端·javascript·react.js
IT_陈寒4 小时前
SpringBoot性能翻倍!这5个隐藏配置让你的应用起飞🚀
前端·人工智能·后端
艾小码5 小时前
别再开无效复盘会了!前端工程师这样复盘,成长速度快人一步
前端