vue实现登录动态路由
实现登录动态路由的基本思路
动态路由的核心是根据用户权限或角色,在登录后动态加载可访问的路由表。Vue Router 提供了 addRoutes 方法(Vue Router 4.x 使用 addRoute)实现这一功能。
定义静态路由和动态路由
静态路由包括无需权限的页面(如登录页、404页),动态路由则根据用户权限生成:

// 静态路由
const constantRoutes = [
{ path: '/login', component: Login },
{ path: '/404', component: NotFound }
]
// 动态路由(示例)
const asyncRoutes = [
{ path: '/admin', component: Admin, meta: { roles: ['admin'] } },
{ path: '/user', component: User, meta: { roles: ['user', 'admin'] } }
]
路由守卫处理登录逻辑
在全局前置守卫中检查用户权限,动态添加路由:
router.beforeEach(async (to, from, next) => {
const hasToken = localStorage.getItem('token')
if (to.path === '/login') {
next()
return
}
if (!hasToken) {
next('/login')
return
}
if (store.getters.routes.length === 0) {
try {
const roles = await store.dispatch('user/getUserInfo')
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
router.addRoutes(accessRoutes)
next({ ...to, replace: true })
} catch (error) {
next('/login')
}
} else {
next()
}
})
Vuex 状态管理
通过 Vuex 管理路由状态和权限数据:

const store = new Vuex.Store({
state: {
routes: [],
addRoutes: []
},
mutations: {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
},
actions: {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
let accessedRoutes
if (roles.includes('admin')) {
accessedRoutes = asyncRoutes
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
}
})
function filterAsyncRoutes(routes, roles) {
return routes.filter(route => {
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role))
} else {
return true
}
})
}
动态菜单渲染
根据生成的路由表渲染侧边栏菜单:
<template>
<div v-for="route in permission_routes" :key="route.path">
<router-link :to="route.path">{{ route.meta.title }}</router-link>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
export default {
computed: {
...mapGetters(['permission_routes'])
}
}
</script>
处理404页面
动态路由添加后,需将404页面路由放在最后:
const router = new VueRouter({
routes: constantRoutes
})
// 添加动态路由后
router.addRoutes([
...accessedRoutes,
{ path: '*', redirect: '/404', hidden: true }
])
注意事项
- 路由的
name属性必须唯一,否则可能导致路由添加失败 - Vue Router 3.x 使用
addRoutes,4.x 使用addRoute逐个添加 - 刷新页面时需要重新获取用户权限信息
- 后端返回的路由数据通常需要转换为组件引用(如
component: () => import('@/views/...'))






