vue实现动态路由的详细代码示例
作者:前端~
vue-router对象中的addRoutes,用它来动态添加路由配置
格式:
router.addRoutes([路由配置对象]) this.$router.addRoutes([路由配置对象])
举个例子:
// 按钮 <button @click="hAddRoute">addRoute</button> // 回调 hAddRoute() { this.$router.addRoutes([{ path: '/abc', component: () => import('@/views/abc'), }]) },
我是以 vue-admin-template 为例,做如下演示:
在router/index.js中的路由配置中 只保留静态路由(因为我们要动态的添加))
const createRouter = () => new Router({ // mode: 'history', // require service support scrollBehavior: () => ({ y: 0 }), routes: [...constantRoutes] //因为要动态添加动态路由,所以这里只写静态路由 })
在permission.js中引入,并使用addRoutes动态添加
这个是 router 下的 index.js中定义的 静态路由、动态路由
接下来来看 在permission.js中引入的内容,
// 引入所有的动态路由表(未经过筛选) + import router, { asyncRoutes } from '@/router' const whiteList = ['/login', '/404'] router.beforeEach(async(to, from, next) => { // 开启进度条 NProgress.start() // 获取本地token 全局getter const token = store.getters.token if (token) { // 有token if (to.path === '/login') { next('/') } else { if (!store.getters.userId) { await store.dispatch('user/getUserInfo') // 改写成动态添加的方式 + router.addRoutes(asyncRoutes) } next() } } else { // 没有token if (whiteList.includes(to.path)) { next() } else { next('/login') } } // 结束进度条 NProgress.done() })
如果我们希望在调用addRoutes方法之后,要路由数据立刻反映到菜单中,我们需要想一个额外的方法,思考一下,vue开发中,哪个技术可以保证响应式特性还可以动态修改? vuex!
补充模块,在src/store/modules下补充menu.js模块 (定义vuex管理菜单数据)
import { constantRoutes } from '@/router' export default { namespaced: true, // 公共数据 state: { // 本地取一下token menuList: [] // 所有可以访问的路由配置 }, mutations: { setMenuList(state, asyncRoutes) { console.log('asyncRoutes', asyncRoutes) //第二个参数是调用mutatains时传过来的动态路由参数 state.menuList = [...constantRoutes, ...asyncRoutes] } } }
当然,要在 src/store/index.js 中注册这个模块
修改src/permission.js中的代码
if (!store.getters.userId) { await store.dispatch('user/getUserInfo') // 动态添加可以访问的路由设置 router.addRoutes(asyncRoutes) // 根据用户实际能访问几个页面来决定从整体8个路由设置 // 中,过滤中出来几个,然后保存到vuex中 ++ store.commit('menu/setMenuList', asyncRoutes) //把动态路由存入vuex中 }
在src\layout\components\Sidebar\index.vue文件中,修改
routes() { // 拿到的是一个完整的包含了静态路由和动态路由的数据结构 return this.$store.state.menu.menuList }
上一步我们实现了: 1.把动态路由通过addRoutes动态添加到了路由系统里, 2. 把动态路由保存到vuex的menu中,
但是我们没有和权限数据做搭配,接下来我们通过接口返回的权限数据对动态菜单做过滤处理,以确定完成菜单与用户权限相关。
接下来就是 调接口,后端返给你菜单数据:
用户能访问哪些页面是通过actions获取到的,只需要从action中返回即可
在permission.js中获取action的返回值并过滤
if (!store.getters.userId) { // 有token,要去的不是login,就直接放行 // 进一步获取用户信息 // 发ajax---派发action来做 const menus = await store.dispatch('user/getUserInfo') console.log('当前用户能访问的页面', menus) console.log('当前系统功能中提供的所有的动态路由页面是', asyncRoutes) // 根据本用户实际的权限menus去 asyncRoutes 中做过滤,选出本用户能访问的页面 const filterRoutes = asyncRoutes.filter(route => { const routeName = route.children[0].name return menus.includes(routeName) }) // 一定要在进入主页之前去获取用户信息 // addRoutes用来动态添加路由配置 // 只有在这里设置了补充了路由配置,才可能去访问页面 // 它们不会出现左侧 router.addRoutes(filterRoutes) // 把它们保存在vuex中,在src\layout\components\Sidebar\index.vue // 生成左侧菜单时,也应该去vuex中拿 store.commit('menu/setMenuList', filterRoutes) }
问题
如果我们刷新浏览器,会发现跳到了404页面
对于addRoute添加的路由,在刷新时会白屏
原因
现在我们的路由设置中的404页处在中间位置而不是所有路由的末尾了。
解决
把404页改到路由配置的最末尾就可以了
filterRoutes.push({ path: '*', redirect: '/404', hidden: true }) //解决刷新去404页面
// 解决刷新出现的白屏bug next({ ...to, // next({ ...to })的目的,是保证路由添加完了再进入页面 (可以理解为重进一次) replace: true // 重进一次, 不保留重复历史 })
效果如下:
总结
到此这篇关于vue实现动态路由的文章就介绍到这了,更多相关vue实现动态路由内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!