每个用户登录后台管理系统看到的侧边栏,访问的路由都不一样
一般有两种方法:第一种是前端写死路由,如果用户没有这个路由权限,就显示你没有访问权限,但这种看到侧边栏有这个模块但看不到就不太好,所以这里讲第二种方法
第二种是由后端传动态路由给前端,具体实现如下:
第一步:
首先确定静态路由,我单独写了一个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和动态路由表
还是前端小白,也借鉴了其他人的写法,大佬勿喷,欢迎指正