vue导航菜单实现
基础导航菜单实现
在Vue中实现基础导航菜单可以通过v-for指令动态渲染菜单项,结合router-link实现路由跳转。需要安装vue-router并配置路由信息。
<template>
<nav>
<ul>
<li v-for="item in menuItems" :key="item.path">
<router-link :to="item.path">{{ item.title }}</router-link>
</li>
</ul>
</nav>
</template>
<script>
export default {
data() {
return {
menuItems: [
{ path: '/', title: '首页' },
{ path: '/about', title: '关于' },
{ path: '/contact', title: '联系我们' }
]
}
}
}
</script>
<style scoped>
nav ul {
list-style: none;
display: flex;
gap: 20px;
}
.router-link-active {
font-weight: bold;
}
</style>
嵌套路由菜单
对于多级菜单,可以使用嵌套路由配置和递归组件。路由配置中添加children属性定义子路由。
// router.js
const routes = [
{
path: '/products',
component: ProductsLayout,
children: [
{ path: '', component: ProductList },
{ path: ':id', component: ProductDetail }
]
}
]
递归组件实现:
<template>
<ul>
<li v-for="item in items" :key="item.path">
<router-link :to="item.path">{{ item.title }}</router-link>
<MenuTree v-if="item.children" :items="item.children"/>
</li>
</ul>
</template>
<script>
export default {
name: 'MenuTree',
props: ['items']
}
</script>
动态权限菜单
根据用户权限过滤显示菜单项,通常需要后端返回权限数据。在Vuex或Pinia中管理权限状态。
// store/modules/auth.js
state: {
permissions: ['dashboard', 'user_management']
},
getters: {
allowedRoutes: (state) => (routes) => {
return routes.filter(route => state.permissions.includes(route.meta.permission))
}
}
菜单组件中使用:
<template>
<nav>
<ul>
<li v-for="route in allowedRoutes" :key="route.path">
<router-link :to="route.path">{{ route.meta.title }}</router-link>
</li>
</ul>
</nav>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['allowedRoutes'])
}
}
</script>
响应式侧边栏
结合CSS媒体查询和Vue的状态管理,实现可折叠的响应式侧边栏。
<template>
<div :class="['sidebar', { 'collapsed': isCollapsed }]">
<button @click="toggleCollapse">≡</button>
<nav>
<!-- 菜单内容 -->
</nav>
</div>
</template>
<style>
.sidebar {
width: 250px;
transition: width 0.3s;
}
.sidebar.collapsed {
width: 60px;
}
@media (max-width: 768px) {
.sidebar {
width: 60px;
}
}
</style>
面包屑导航
通过路由元信息和$route.matched数组生成面包屑路径。
<template>
<div class="breadcrumbs">
<span v-for="(match, index) in $route.matched" :key="index">
<router-link v-if="index < $route.matched.length - 1" :to="match.path">
{{ match.meta.breadcrumb }}
</router-link>
<span v-else>{{ match.meta.breadcrumb }}</span>
<span v-if="index < $route.matched.length - 1"> / </span>
</span>
</div>
</template>
路由配置示例:
{
path: '/user/:id',
meta: { breadcrumb: '用户详情' }
}






