vue中实现动态路由
vue-router 基础配置
安装 vue-router 依赖包
npm install vue-router
在 main.js 中初始化路由实例
import Vue from 'vue'
import VueRouter from 'vue-router'
Vue.use(VueRouter)
const router = new VueRouter({
mode: 'history',
routes: []
})
静态路由定义
定义基础路由表结构
const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login.vue')
},
{
path: '/404',
component: () => import('@/views/404.vue')
}
]
动态路由实现方案
获取用户权限数据
// 通常从接口获取
const getAsyncRoutes = async () => {
return await api.getUserRoutes()
}
路由表转换函数
function filterRoutes(routeList) {
return routeList.map(route => {
const { path, componentPath, children } = route
return {
path,
component: () => import(`@/views/${componentPath}`),
children: children ? filterRoutes(children) : []
}
})
}
路由动态加载
在导航守卫中处理
router.beforeEach(async (to, from, next) => {
if (!store.getters.routesLoaded) {
const asyncRoutes = await getAsyncRoutes()
const formattedRoutes = filterRoutes(asyncRoutes)
router.addRoutes(formattedRoutes)
store.commit('SET_ROUTES', formattedRoutes)
next({ ...to, replace: true })
} else {
next()
}
})
路由数据缓存
使用 Vuex 存储路由状态
const store = new Vuex.Store({
state: {
routes: []
},
mutations: {
SET_ROUTES(state, routes) {
state.routes = routes
}
},
getters: {
routesLoaded: state => state.routes.length > 0
}
})
路由元信息配置
定义路由权限元数据
{
path: '/admin',
component: AdminLayout,
meta: {
requiresAuth: true,
roles: ['admin']
}
}
路由权限校验
在导航守卫中添加权限验证
router.beforeEach((to, from, next) => {
if (to.matched.some(record => record.meta.requiresAuth)) {
if (!store.getters.isAuthenticated) {
next('/login')
} else if (to.meta.roles && !to.meta.roles.includes(store.getters.role)) {
next('/403')
} else {
next()
}
} else {
next()
}
})
动态路由常见问题处理
解决刷新路由丢失问题
// 在应用初始化时加载路由
async function initializeApp() {
if (localStorage.getItem('token')) {
await store.dispatch('loadRoutes')
}
}
404页面兜底配置
{
path: '*',
redirect: '/404'
}
路由模块化处理
拆分路由配置文件
// router/modules/
import userRoutes from './user'
import adminRoutes from './admin'
export default [...userRoutes, ...adminRoutes]
路由懒加载优化
使用 webpack 魔法注释
component: () => import(/* webpackChunkName: "user" */ '@/views/user.vue')
路由过渡动画
添加全局过渡效果
<template>
<transition name="fade">
<router-view />
</transition>
</template>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>






