vue动态路由实现

8 篇文章 0 订阅
7 篇文章 0 订阅

什么是动态路由

动态路由,顾名思义,就是路由不在前端被写死,而是通过后端返回并渲染。这样做的好处主要有可以根据用户权限来展示不一样的页面层级,也可以随时配置路由信息,不用修改源码。

如何实现

既然这么好用,那么如何实现呢?

当然,这里需要一个接口来返回你所需要的路由信息,如果不会java可以用node来写,这里附上我的另一篇文章node.js写后台接口连接数据库

至于前端实现,废话不多说直接上代码。

首先需要获取路由信息和处理数据以及存储等,所以需要在store下创建一个module,至于store的使用可以看我另一篇文章vuex的使用。这里我给他命名为permission.js

store/modules/permission.js

import { constantRoutes } from '@/router'//部分写死的路由,比如login
import { getRouters } from '@/api/login'//后台请求调用
import Layout from '@/layout/index'

const permission = {
  state: {
    routes: [],
    addRoutes: []
  },
  mutations: {
    SET_ROUTES: (state, routes) => {
      state.addRoutes = routes
      state.routes = constantRoutes.concat(routes)
    }
  },
  actions: {
    // 生成路由
    GenerateRoutes({ commit }) {
      return new Promise(resolve => {
        // 向后端请求路由数据
        getRouters().then(res => {//请求路由数据
          const accessedRoutes = filterAsyncRouter(res.data.router)//对请求回的路由进行处理
          accessedRoutes.push({ path: '*', redirect: '/404', hidden: true })
          commit('SET_ROUTES', accessedRoutes)
          resolve(accessedRoutes)
        })
      })
    }
  }
}

// 遍历后台传来的路由字符串,转换为组件对象
function filterAsyncRouter(asyncRouterMap) {
  return asyncRouterMap.filter(route => {
    if (route.component) {
      // Layout组件特殊处理
      if (route.component === 'Layout') {
        route.component = Layout
      } else {
        route.component = loadView(route.component)
      }
    }
    if (route.children != null && route.children && route.children.length && route.children != []) {
      route.children = filterAsyncRouter(route.children)
    }else{
      delete route.children
      delete route.alwaysShow
    }
    return true
  })
}
// 用作对组件解析,views是你存放页面的文件夹,根据需要自行调整
export const loadView = (view) => { // 路由懒加载
  return (resolve) => require([`@/views/${view}`], resolve)
}

export default permission

然后根目录创建一个文件,命名随意(我这里叫permission.js),这个文件主要作用就是路由拦截

permission.js

import router from './router'
import store from './store'

// 消息提醒
import { Message } from 'element-ui'

// 进度条
import NProgress from 'nprogress'
import 'nprogress/nprogress.css'

// 最重要: 在路由加载跳转前调用的方法
router.beforeEach((to, from, next) => {// to是要跳转的路径信息
  // 打开进度条
  NProgress.start()
  if (判断token是否获取到) {
    if (to.path === '/login') {
      next({ path: '/' })
      NProgress.done()
    } else {
      if (条件) {
        // 判断当前用户是否拉取过路由信息,如果没有获取过路由信息再进行以下步骤
        store.dispatch('GenerateRoutes').then(accessRoutes => {
          router.addRoutes(accessRoutes) // 动态添加可访问路由表
          next({ ...to, replace: true }) // hack方法 确保addRoutes已完成
        })
      } else {
        next()
      }
    }
  } else {
    // 没有token
    if (判断是否是不需要登录的页面  eg:免登录的地址组成的数组.indexOf(to.path) !== -1) {
      // 在免登录白名单,直接进入
      next()
    } else {
      next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页
      NProgress.done()
    }
  }
})
// 路由跳转后方法
router.afterEach(() => {
  NProgress.done()
})

最后,在main.js中引入该文件使其生效

main.js

import '@/permission' // 引入@/permission.js,使其生效

剩下的就是左侧菜单的配置,这个根据你们自己使用的方法,从vuex中读取路由数据来渲染菜单。

写在最后

喜欢这篇文章的小伙伴们,留个赞再走吧
比心

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

梓齐丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值