Vue学习笔记-左侧菜单优化:高亮、激活状态、折叠侧边栏

 作者:一名 Vue 的学习者
 记录时间:2025年12月
 目标:优化上一节实现的菜单,实现 选中菜单 高亮、激活,可折叠。效果图如下:

Vue学习笔记-左侧菜单优化:高亮、激活状态、折叠侧边栏

菜单折叠高亮


上一篇我已经把后台最基础的布局(头部 + 左侧菜单 + 内容区 + 页脚)搭建好了,但左侧菜单目前还是一个超级“简陋”的版本:

  • 只有静态数据
  • 点击后不会高亮
  • 路由切换看不出当前在哪
  • 菜单太宽时无法折叠
  • 也不支持子菜单

所以这一篇我继续把 Sidebar 进行 “精装修”做得更像后台系统,将会实现:

  1. 高亮当前菜单项(根据路由自动匹配)
  2. 点击菜单后的激活状态
  3. 简单实现菜单折叠(Collapse)
  4. 布局自适应折叠宽度
  5. 为后面动态菜单奠定基础

1. 让菜单能“知道”当前在哪个页面

Vue3 + Vue Router 的组合超级友善,我可以通过 useRoute 获取当前路由对象,通过它的 path 来判断是否选中。

先到 Sidebar 使用 route 信息

Sidebar.vue

<script setup>
import { useRouter, useRoute } from "vue-router";
const router = useRouter();
const route = useRoute();
const menus = [
  { title: "首页", path: "/" },
  { title: "用户管理", path: "/user" },
  { title: "系统设置", path: "/setting" }
];
function go(path) {
  router.push(path);
}
</script>

在模板中判断是否高亮

<div
  class="menu-item"
  :class="{ active: route.path === item.path }"
  v-for="item in menus"
  :key="item.path"
  @click="go(item.path)"
>
  {{ item.title }}
</div>

给 active 加上样式

.menu-item.active {
  background: #e0ecff;
  color: #2d8cf0;
  font-weight: bold;
}

至此,左侧菜单已经能“随着路由变化自动高亮”。


2. 实现菜单折叠(Collapse)

折叠菜单几乎是后台标配,我想实现一个简单版本:

  • 点击按钮后,菜单从 200px → 60px
  • 只显示图标,不显示文字(本篇先不做图标,但结构要预留)
  • 内容区自动拉伸

为了实现折叠,我先在 Sidebar 的父级 Layout 中放一个“折叠按钮”。


2.1 在 Header 加一个折叠按钮

Header.vue

<template>
  <div class="layout-header">
    <div class="logo">
      My Admin
    <button class="collapse-btn" @click="$emit('toggleMenu')"></button>
    </div>
    <div class="right">
      <span class="user">Hello, User</span>
      <button class="logout">退出</button>
    </div>
  </div>
</template>
<style scoped>
.collapse-btn {
  margin-left: 20px;
  background: none;
  border: none;
  color: #fff;
  cursor: pointer;
  font-size: 22px;
}
</style>

2.2 在 Layout 中接收折叠事件

layout/index.vue

<script setup>
import { ref } from "vue";
import Header from "./Header.vue";
import Sidebar from "./Sidebar.vue";
import Footer from "./Footer.vue";
const collapsed = ref(false);
function toggleMenu() {
  collapsed.value = !collapsed.value;
}
</script>
<template>
  <div class="layout-container">
    <Header @toggleMenu="toggleMenu" />

    <div class="layout-body">
      <Sidebar :collapsed="collapsed" />

      <div class="layout-content">
        <router-view />
      </div>
    </div>
    <Footer />
  </div>
</template>

让 Sidebar 接收 collapsed 状态。


2.3 Sidebar 根据 collapsed 调整宽度

Sidebar.vue

<template>
  <div
    class="layout-sidebar"
    :style="{ width: collapsed ? '60px' : '200px' }"
  >
    <div
      class="menu-item"
      :class="{ active: route.path === item.path }"
      v-for="item in menus"
      :key="item.path"
      @click="go(item.path)"
    >
      <!-- 文字折叠时隐藏 -->
      <span v-if="!collapsed">{{ item.title }}</span>
    </div>
  </div>
</template>
<script setup>
const props = defineProps({
  collapsed: Boolean
});
</script>

折叠相关样式优化

.layout-sidebar {
  background: #f7f7f7;
  height: calc(100vh - 56px - 40px);
  transition: width 0.2s; /* 动画效果 */
}

.menu-item {
  padding: 12px 20px;
  cursor: pointer;
  white-space: nowrap;
}

折叠后,菜单变窄,但仍能正常点击,也预留了图标空间,让后续扩展更容易。


3. 路由变动时菜单自动更新高亮

之前已经用 route.path 做了高亮,但我想进一步优化:

  • 若后来菜单有二级路径 /user/list /user/info
  • 我希望 /user 对应的一级菜单自动激活

因此我改成:

:class="{ active: route.path.startsWith(item.path) }"

这样即使进入 /user/detail?id=1 菜单也会正确激活。


4. 给菜单激活项增加视觉效果

我做了两件小改动:

① 左侧加高亮条

.menu-item.active {
  background: #eaf2ff;
  color: #2d8cf0;
  font-weight: bold;
  border-left: 3px solid #2d8cf0;
}

② hover 效果更柔和

.menu-item:hover {
  background: #f1f1f1;
}

菜单变得更有后台“质感”了。


5. 小结:Sidebar 功能越来越像样了

这一篇我让左侧菜单比之前更“后台系统化”,主要做了三件事:

1. 当前路由自动高亮:通过 route.path 判断激活状态,切页后高亮同步更新。
2. 菜单折叠:菜单从 200px → 60px,折叠/展开带动画,布局自适应。
3. 更逼真的视觉效果:高亮条、柔和的 hover、隐藏文字。

这些都是后台系统侧边栏最基础也最必要的功能,随着菜单功能越来越完善,后续还将增加:

  • 支持二级、三级菜单 和 多级菜单
  • 增加菜单图标
  • 使用element-plus框架优化菜单和布局
  • 增加模拟登录页 + 真实后端请求登录
  • 动态路由 + 后端返回菜单
  • 权限控制
  • 菜单缓存、展开状态保持

这些我会在后续的章节继续完成。


下一步计划:增加多级菜单 和 图标,使用Element-plus库进行美化!

© 版权声明
THE END
如果内容对您有所帮助,就支持一下吧!
点赞0 分享
唱点熟悉的段落的头像 - 鹿快
评论 共2条

请登录后发表评论

    暂无评论内容