vue实现菜单导航
Vue 实现菜单导航的方法
使用 Vue Router 实现基础导航
安装 Vue Router 依赖:
npm install vue-router
在 main.js 或 router/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>






