当前位置:首页 > VUE

vue实现菜单导航

2026-02-18 14:05:11VUE

Vue 实现菜单导航的方法

使用 Vue Router 实现基础导航

安装 Vue Router 依赖:

npm install vue-router

main.jsrouter/index.js 中配置路由:

import { createRouter, createWebHistory } from 'vue-router'
import Home from './views/Home.vue'
import About from './views/About.vue'

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
]

const router = createRouter({
  history: createWebHistory(),
  routes
})

export default router

在 App.vue 中使用 <router-view><router-link>

<template>
  <div>
    <nav>
      <router-link to="/">Home</router-link>
      <router-link to="/about">About</router-link>
    </nav>
    <router-view></router-view>
  </div>
</template>

动态生成菜单项

创建可配置的菜单数据:

// menuItems.js
export default [
  { path: '/', name: 'Home' },
  { path: '/about', name: 'About' },
  { path: '/contact', name: 'Contact' }
]

在组件中动态渲染:

<template>
  <nav>
    <router-link 
      v-for="item in menuItems" 
      :key="item.path" 
      :to="item.path"
    >
      {{ item.name }}
    </router-link>
  </nav>
</template>

<script>
import menuItems from './menuItems'
export default {
  data() {
    return {
      menuItems
    }
  }
}
</script>

嵌套路由实现多级菜单

配置嵌套路由:

const routes = [
  {
    path: '/products',
    component: Products,
    children: [
      { path: 'list', component: ProductList },
      { path: 'detail/:id', component: ProductDetail }
    ]
  }
]

渲染嵌套菜单:

<template>
  <div v-for="category in menuCategories" :key="category.path">
    <router-link :to="category.path">{{ category.name }}</router-link>
    <div v-if="category.children">
      <router-link 
        v-for="child in category.children" 
        :key="child.path"
        :to="child.path"
      >
        {{ child.name }}
      </router-link>
    </div>
  </div>
</template>

添加菜单交互效果

使用 CSS 实现悬停效果:

nav a {
  padding: 8px 16px;
  transition: background-color 0.3s;
}

nav a:hover {
  background-color: #f0f0f0;
}

.router-link-active {
  font-weight: bold;
  border-bottom: 2px solid #42b983;
}

添加折叠功能:

<template>
  <div v-for="item in menuItems" :key="item.path">
    <div @click="toggleSubmenu(item)">
      {{ item.name }}
      <span v-if="item.children">{{ isOpen(item) ? '▲' : '▼' }}</span>
    </div>
    <div v-show="isOpen(item)" v-if="item.children">
      <router-link 
        v-for="child in item.children" 
        :key="child.path"
        :to="child.path"
      >
        {{ child.name }}
      </router-link>
    </div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      openItems: []
    }
  },
  methods: {
    toggleSubmenu(item) {
      const index = this.openItems.indexOf(item.path)
      if (index > -1) {
        this.openItems.splice(index, 1)
      } else {
        this.openItems.push(item.path)
      }
    },
    isOpen(item) {
      return this.openItems.includes(item.path)
    }
  }
}
</script>

响应式菜单实现

使用媒体查询和 Vue 状态管理:

<template>
  <button @click="toggleMobileMenu">☰</button>
  <nav :class="{ 'mobile-hidden': !showMobileMenu }">
    <!-- 菜单内容 -->
  </nav>
</template>

<script>
export default {
  data() {
    return {
      showMobileMenu: false,
      isMobile: window.innerWidth < 768
    }
  },
  mounted() {
    window.addEventListener('resize', this.handleResize)
  },
  beforeUnmount() {
    window.removeEventListener('resize', this.handleResize)
  },
  methods: {
    toggleMobileMenu() {
      this.showMobileMenu = !this.showMobileMenu
    },
    handleResize() {
      this.isMobile = window.innerWidth < 768
      if (!this.isMobile) {
        this.showMobileMenu = false
      }
    }
  }
}
</script>

<style>
@media (max-width: 768px) {
  nav {
    display: none;
  }
  .mobile-hidden {
    display: none;
  }
}
</style>

权限控制菜单显示

根据用户角色过滤菜单项:

// 在路由配置中添加 meta 字段
const routes = [
  { 
    path: '/admin', 
    component: Admin,
    meta: { requiresAuth: true, roles: ['admin'] }
  }
]

使用导航守卫和菜单过滤:

// router/index.js
router.beforeEach((to, from, next) => {
  const userRole = getUserRole() // 获取用户角色
  if (to.meta.roles && !to.meta.roles.includes(userRole)) {
    next('/forbidden')
  } else {
    next()
  }
})

在组件中过滤菜单:

<script>
import menuItems from './menuItems'
export default {
  computed: {
    filteredMenuItems() {
      const userRole = this.$store.state.user.role
      return menuItems.filter(item => {
        return !item.meta?.roles || item.meta.roles.includes(userRole)
      })
    }
  }
}
</script>

vue实现菜单导航

标签: 菜单vue
分享给朋友:

相关文章

vue实现双折线图

vue实现双折线图

实现双折线图的步骤 安装必要的依赖库(如 ECharts 或 Chart.js),这里以 ECharts 为例: npm install echarts --save 在 Vue 组件中引入 ECh…

vue实现jqueryui

vue实现jqueryui

Vue 实现 jQuery UI 功能 在 Vue 项目中实现类似 jQuery UI 的功能,可以通过原生 Vue 组件或第三方库来实现。以下是几种常见 jQuery UI 功能的 Vue 替代方案…

vue实现fadein

vue实现fadein

Vue 实现 FadeIn 效果 在 Vue 中实现淡入(FadeIn)效果可以通过 CSS 过渡、动画或第三方库实现。以下是几种常见方法: 使用 CSS 过渡 通过 Vue 的过渡系统结合 CS…

vue实现布局

vue实现布局

Vue 实现布局方法 Vue 提供了多种方式实现页面布局,可以通过组件化、CSS 框架或自定义样式完成。以下是几种常见方法: 使用 CSS Flexbox 或 Grid 通过 Vue 单文件组件结…

vue实现答题

vue实现答题

Vue 实现答题功能 数据结构设计 使用 Vue 的响应式特性管理题目和答案数据。通常需要以下数据结构: data() { return { questions: [ {…

vue实现表单

vue实现表单

Vue 表单实现方法 双向数据绑定 使用 v-model 指令实现表单元素与数据的双向绑定。适用于 input、textarea、select 等元素。 <template> &l…