生活知识集
第二套高阶模板 · 更大气的阅读体验

用Vue做一个实用的菜单导航组件

发布时间:2025-12-25 18:10:59 阅读:37 次

做网站的时候,菜单导航几乎是每个项目都绕不开的部分。特别是在用 Vue 开发单页应用时,一个结构清晰、样式灵活的菜单导航组件能让整个页面看起来更专业,也方便用户操作。比如你做个后台管理系统,左边侧边栏一堆功能入口,用 Vue 来组织这些菜单项就特别顺手。

从最简单的结构开始

先不考虑复杂逻辑,只搭一个基础的横向菜单。HTML 结构可以用 ul 和 li 来写,再通过 Vue 控制点击切换当前激活项。

<template>
  <nav class="nav-menu">
    <ul>
      <li 
        v-for="(item, index) in menuItems" 
        :key="index" 
        :class="{ active: activeIndex === index }"
        @click="handleClick(index)"
      >
        {{ item.label }}
      </li>
    </ul>
  </nav>
</template>

<script>
export default {
  data() {
    return {
      activeIndex: 0,
      menuItems: [
        { label: '首页' },
        { label: '关于' },
        { label: '服务' },
        { label: '联系' }
      ]
    };
  },
  methods: {
    handleClick(index) {
      this.activeIndex = index;
    }
  }
};
</script>

<style scoped>
.nav-menu ul {
  display: flex;
  list-style: none;
  padding: 0;
  margin: 0;
}

.nav-menu li {
  padding: 12px 20px;
  cursor: pointer;
}

.nav-menu li.active {
  background-color: #007bff;
  color: white;
  border-radius: 4px;
}
</style>

支持多级嵌套的侧边栏

实际开发中,菜单往往不止一层。比如后台常见的“用户管理”下面还有“列表”“添加”等子项。这时候可以把数据结构改成嵌套形式,通过递归组件来渲染。

先定义带 children 的菜单数据:

menuItems: [
  {
    label: '仪表盘',
    path: '/dashboard'
  },
  {
    label: '用户管理',
    children: [
      { label: '用户列表', path: '/users' },
      { label: '新增用户', path: '/users/add' }
    ]
  }
]

然后创建一个递归组件 SidebarItem.vue:

<template>
  <div class="sidebar-item">
    <div 
      v-if="!item.children" 
      class="menu-link" 
      @click="$router.push(item.path)"
    >
      {{ item.label }}
    </div>
    
    <div v-else>
      <div class="menu-parent" @click="isExpanded = !isExpanded">
        {{ item.label }}
        <span>{{ isExpanded ? '▼' : '▶' }}</span>
      </div>
      
      <transition name="slide">
        <div v-show="isExpanded" class="submenu">
          <SidebarItem 
            v-for="child in item.children" 
            :key="child.path" 
            :item="child" 
          />
        </div>
      </transition>
    </div>
  </div>
</template>

<script>
export default {
  name: 'SidebarItem',
  props: ['item'],
  data() {
    return {
      isExpanded: false
    };
  }
};
</script>

结合 Vue Router 实现高亮

在真实项目里,菜单通常和路由联动。当进入某个页面时,对应的菜单项自动变色或加粗。利用 Vue Router 提供的 $route 对象就能轻松实现。

比如判断当前路径是否匹配:

:class="[$style.menuItem, {
  [$style.active]: item.path === $route.path
}]"

或者更灵活一点,判断是否是父级路径:

computed: {
  isActive() {
    const currentPath = this.$route.path;
    return currentPath.startsWith(this.item.path);
  }
}

这样进到 /users/123 编辑页时,“用户列表”那一项依然能保持高亮状态,用户体验会更好。

小细节优化

加个折叠图标、过渡动画、键盘上下键切换选中项,这些小改进会让组件更顺滑。比如给展开收起加上 CSS 过渡:

.slide-enter-active, .slide-leave-active {
  transition: height 0.3s ease;
}
.slide-enter-to {
  height: auto;
}
.slide-enter, .slide-leave-to {
  height: 0;
  overflow: hidden;
}

平时自己搭项目,这种导航组件写一次之后可以直接复制粘贴复用。时间一长,慢慢就攒出一套自己的组件库了,效率提升很明显。