vue后台管理系统动态路由的实现

每个用户登录后台管理系统看到的侧边栏,访问的路由都不一样
一般有两种方法:第一种是前端写死路由,如果用户没有这个路由权限,就显示你没有访问权限,但这种看到侧边栏有这个模块但看不到就不太好,所以这里讲第二种方法
第二种是由后端传动态路由给前端,具体实现如下:

第一步:
首先确定静态路由,我单独写了一个js文件

//router.constantRouterMap.js
const constantRouterMap = [
  {
    path: '/',
    redirect: '/login',
  },
  //登录模块
  {
    path: '/login',
    name: 'login',
    meta: {
      title: '登录',
    },
    component: () => import('@/views/loginModule/login/login.vue'),
  },
  //注册
  {
    path: '/register',
    name: 'register',
    meta: {
      title: '注册',
    },
    component: () => import('@/views/loginModule/register/register.vue'),
  },
  //忘记密码
  {
    path: '/forget',
    name: 'forget',
    meta: {
      title: '忘记密码',
    },
    component: () => import('@/views/loginModule/forget/forget.vue'),
  },
  //微信扫码
  {
    path: '/scan',
    name: 'scan',
    meta: {
      title: '扫码登录',
    },
    component: () => import('@/views/loginModule/scan/scan.vue'),
  },
  //主体
  {
    path: '/main',
    name: 'main',
    component: () => import('@/views/main/main.vue'),
  }
]

export default constantRouterMap

然后在router.index里面引入,这样就引入了静态路由

//router.index
import Vue from 'vue'
import VueRouter from 'vue-router'
import constantRouterMap from './constantRouterMap'
import lastRouter from './lastRouter'
Vue.use(VueRouter)

import NProgress from 'nprogress'
import 'nprogress/nprogress.css'

import store from '.././store/index'
import Main from '../views/main/main.vue'

const router = new VueRouter({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: constantRouterMap
})

export default router

第二步:
在登录的时侯把token存在缓存中,每次请求的时侯都要从缓存里拿到这个token
这里我们封装在请求头里
缓存我用的是vue-ls存放在main.js里全局引入,可以去下载npm依赖包,也可以直接用localStorage
在vuex里面调用动态路由

//main.js
import VueStorage from 'vue-ls'
Vue.use(VueStorage, {
  namespace: 'pro__', // key prefix
  name: 'ls', // name variable Vue.[ls] or this.[$ls],
  storage: 'local', // storage name session, local, memory
})

封装axios,把token放在请求头里

//http.js文件
import axios from 'axios'
import Vue from 'vue'
axios.defaults.timeout = 5000
axios.defaults.baseURL = ''//ip+端口号

axios.interceptors.request.use(
  (config) => {
    config.data = JSON.stringify(config.data)
    config.headers = {
      'Content-Type': 'application/json',
      token: Vue.ls.get('token'),
    }
    return config
  },
  (err) => {
    return Promise.reject(err)
  }
)
//封装axios.get方法
function get(url, params = {}) {
  return new Promise((resolve, reject) => {
    axios
      .get(url, { params: params })
      .then((response) => {
        resolve(response.data)
      })
      .catch((err) => {
        reject(err)
      })
  })
}

export default {
  get: get,
}

单独建一个文件专门放调用接口方法

//使用axios.get方法
import http from './http'
export const api={
	// 获取侧边栏,权限数组
  getPermissionList(params) {
    return http.get('acl/index/menu', params)
  },
}

//store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
import { api } from '../server/api'
export default new Vuex.Store({
  state: {
    list: [],
  },
  mutations: {
    setList: (state, data) => {
      state.list = data
    },
  },
  actions: {
    async getPermission({ commit }) {
      // 取后台路由
      let asyncRouter = await api.getPermissionList()
      // 存储权限列表
      return new Promise((resolve) => {
        const pml = asyncRouter.data.permissionList.children
        commit('setList', pml)
        resolve(pml)
      })
    },

第三步:
然后在router.index写路由的守卫前置去拉取动态路由表
再lastRouter里写404页面等

//router.index.js
//路由守卫,路由跳转之前的钩子
router.beforeEach((to, from, next) => {
  NProgress.start()
  /* 路由发生变化修改页面title */
  if (to.meta.title) {
    document.title = to.meta.title
  }
  next()

  if (!Vue.ls.get('token')) {
    if (
      to.path === '/login' ||
      to.path === '/register' ||
      to.path === '/forget' ||
      to.path === '/scan' ||
      to.path === 'main'
    ) {
      next()
      NProgress.done()
    } else {
      next('/login')
      NProgress.done()
    }
  } else {
    if (
      to.path === '/login' ||
      to.path === '/register' ||
      to.path === '/forget' ||
      to.path === 'main' ||
      to.path === '/scan'
    ) {
      next()
      NProgress.done()
    } else {
      if(store.state.list.length===0){
        store.dispatch('getPermission').then((res) => {
        //component是头部包括侧边栏不需要跳转变化的部分
          let routesFilter = res.filter((r) => (r.component = Main))
          // console.log(routesFilter)
          routesFilter.forEach((r) => {
            if (r.children) {
              r.children.forEach((rr) => {
                const component = rr.component
                rr.component = (resolve) =>
                  require(['@/views' + component], resolve)
              })
            }
          })
          router.addRoutes(routesFilter)
          router.addRoutes(lastRouter)
          next({ ...to, replace: true })
          NProgress.done()
        })
      }else{
        next()
        NProgress.done()
      }
    }
  }
})

router.afterEach(() => {
  NProgress.done()
})

//router.lastRouter.js
//404要放在最后加载
const lastRouter = [
    //用户中心
    {
      path: '/user',
      name: 'user',
      meta: {
        title: '用户中心',
      },
      component: () => import('@/views/user/user.vue'),
      children: [
        {
          path: '/user',
          redirect: '/user/setup',
        },
        //基本设置
        {
          path: '/user/setup',
          name: 'setup',
          meta: {
            title: '基本设置',
          },
          component: () => import('@/views/user/setup/setup.vue'),
        },
        //修改密码
        {
          path: '/user/set-password',
          name: 'set-password',
          meta: {
            title: '修改密码',
          },
          component: () => import('@/views/user/set-password/set-password.vue'),
        },
      ],
    },
    //404页面
    {
      path: '*',
      name: '404',
      meta: {
        title: '404',
      },
      component: () => import('@/views/404/404.vue'),
    }
  ]
  
  export default lastRouter

到这里动态路由表就拉取结束了,记得退出登录的时侯清空token和动态路由表
还是前端小白,也借鉴了其他人的写法,大佬勿喷,欢迎指正

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值