Vue2极简教程006-点击菜单出发了路由切换
Vue2极简教程006:实现菜单路由切换的完整方案
一、基础路由切换实现
1. 菜单组件结构
<template>
<div class="menu-container">
<!-- 使用router-link实现导航 -->
<router-link
v-for="item in menuItems"
:key="item.path"
:to="item.path"
class="menu-item"
active-class="active"
>
{{ item.title }}
</router-link>
</div>
</template>
<script>
export default {
data() {
return {
menuItems: [
{ title: '首页', path: '/' },
{ title: '产品中心', path: '/products' },
{ title: '关于我们', path: '/about' }
]
}
}
}
</script>
<style scoped>
.menu-item {
display: inline-block;
padding: 10px 20px;
cursor: pointer;
}
.active {
border-bottom: 2px solid #42b983;
color: #42b983;
}
</style>
2. 路由配置示例
// router/index.js
const routes = [
{
path: '/',
name: 'Home',
component: () => import('../views/Home.vue')
},
{
path: '/products',
name: 'Products',
component: () => import('../views/Products.vue')
},
{
path: '/about',
name: 'About',
component: () => import('../views/About.vue')
}
]
二、进阶功能实现
1. 编程式导航控制
<template>
<div class="menu-item"
v-for="item in menuItems"
:key="item.path"
@click="handleMenuClick(item)">
{{ item.title }}
</div>
</template>
<script>
export default {
methods: {
handleMenuClick(item) {
// 路由跳转
this.$router.push(item.path)
// 或者带参数跳转
// this.$router.push({
// name: item.name,
// params: { id: 123 }
// })
// 添加跳转逻辑
if (item.requireAuth && !this.isLogin) {
this.$router.push('/login')
}
}
}
}
</script>
2. 动态菜单高亮
computed: {
activeMenu() {
return this.$route.path // 根据当前路由自动高亮
}
}
三、企业级最佳实践
1. 权限菜单方案
// 过滤有权限的菜单项
computed: {
filteredMenus() {
return this.menuItems.filter(item => {
return !item.meta?.requiresAuth || this.$store.getters.hasPermission
})
}
}
// 路由配置中添加元信息
{
path: '/admin',
meta: { requiresAuth: true }
}
2. 面包屑导航集成
// 面包屑组件
computed: {
breadcrumbs() {
const matched = this.$route.matched.filter(r => r.meta?.title)
return matched.map(route => ({
title: route.meta.title,
path: route.path
}))
}
}
四、常见问题解决方案
1. 菜单刷新后高亮丢失
// 使用路由name替代path作为标识
activeClass() {
return this.$route.name === this.menuItem.name ? 'active' : ''
}
2. 路由重复点击报错
// 重写router.push方法
const originalPush = VueRouter.prototype.push
VueRouter.prototype.push = function push(location) {
return originalPush.call(this, location).catch(err => err)
}
3. 菜单动画效果
<transition name="fade">
<router-view></router-view>
</transition>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
五、完整项目结构示例
src/
├── components/
│ └── Menu.vue # 导航菜单组件
├── router/
│ ├── index.js # 路由配置
│ └── routes.js # 路由定义
├── views/
│ ├── Home.vue
│ ├── Products.vue
│ └── About.vue
└── store/
└── modules/
└── menu.js # 菜单状态管理
六、性能优化建议
路由懒加载:
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
菜单数据缓存:
created() { if (!this.$store.state.menu.loaded) { this.$store.dispatch('menu/fetchMenus') } }
滚动行为控制:
const router = new VueRouter({ scrollBehavior(to, from, savedPosition) { return { x: 0, y: 0 } } })
扩展建议:对于复杂中后台系统,推荐使用vue-element-admin的菜单方案
通过本教程,你可以实现:
- 声明式的菜单路由绑定
- 灵活的权限控制方案
- 流畅的过渡动画效果
- 企业级的导航交互体验