this.$store.dispatch('Login',this.loginForm)
.then(res=>{
this.loading = false;
this.$router.push('/');
})//登陆用vuex,这样方便全局的管理
store.js
import Vue from 'vue'
import Vuex from 'vuex'
import user from './modules/user'
import permission from './modules/permission'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
user,
permission
}
})//这里分成两个模块方便日后的维护
user.js
export default {
state: {
token:getToken(),//这就是从网页中存存储的token取出
//下面有token存在哪的解释,当然你存在哪他就从哪取出来
roles:[]//角色权限的数组
},
getters:{
token:state=>state.token,
roles:state=>state.roles,
},
mutations: {
SET_TOKEN(state,token){
state.token = token;
},
SET_ROLES(state,roles){
state.roles = roles;
}
},
actions: {
Login({commit},user){
return new Promise((resolve,reject)=>{
loginApi(user).then(res=>{//这是请求登陆接口的ajax
commit('SET_TOKEN',res.data.token);//这时候后端会返回一个token
setToken(res.data.token);//把后端返回的token存起来
//这里是封装了个方法把token存在了cookie中
//你也可以存在sessionStorage或者locationStorage中
resolve(res);
}).catch(err=>{
reject(err);
})
})
},
GetInfo({commit,state}){//这是获取用户的角色信息
//是超级管理员还是普通的
//这里返回的格式是数组['inputs']或者['admin']...
return new Promise((resolve,reject)=>{
getInfoApi(state.token).then(res=>{//请求接口
commit('SET_ROLES',res.data.roles);
resolve(res.data);
}).catch(err=>{
reject(err);
})
})
},
},
}
permission.js
//这里是两个分类路由
//asyncRouters动态变化的路由
//constantRouters永远不变的路由,就是什么权限都有他
import {asyncRouters,constantRouters} from '@/router/index.js'
function filterAsyncRoutes(routes, v) {//这是对路由函数的定义
const res = []
routes.forEach((route,i) => {//对每个路由进行判断
//深拷贝,防止第二次登陆换权限的时候路由没有发生改变
//这里如果你不用深拷贝直接赋值的话,你换账号登陆的时候他路由加载会不完全
//有兴趣你可以试试
var newRoute = deep({},route)
newRoute.children = route.children.filter(item=>{//对权限进行过滤
if(item.meta && item.meta.roles && v.some(role => item.meta.roles.includes(role))){
//刚才vuex中定义的roles这时候就用到了
//判断子路由中是否存在roles这个值有就返回
return item
}
})
if(newRoute.children.length>0){//判断下是否有子路由,有的话就添加
res.push(newRoute)
}
});
return res;
}
const state = {
routes: []//动态路由存在vuex中这样没次刷新的时候他都能判断一次提高安全性
}
const getters = {
permission_routes: state => state.routes, //权限路由
}
const mutations = {
SET_ROUTES: (state, routes) => {
state.routes = constantRouters.concat(routes)//和永远不变的路由添加到一起
}
}
const actions = {
GenerateRoutes({ commit }, roles) {//角色数组['']
return new Promise(resolve => {
let accessedRoutes;
if (roles.includes("admin")) {//如果权限是admin就不用判断了就都添加进去
accessedRoutes = asyncRouters ;
} else {
accessedRoutes = filterAsyncRoutes(asyncRouters, roles) //不是管理员跟据meta过滤数据
}
commit('SET_ROUTES', accessedRoutes);
resolve(accessedRoutes);
})
}
}
export default {
state,
getters,
mutations,
actions
}
路由守卫的js
router.beforeEach(async(to,from,next)=>{
if(to.path=='/login'){// 1.判断是否登陆界面
next();
}else{
//如果不是登陆就要进行判断了
// 这里是动态获取这个权限,
//因为存进vuex刷新是时候vuex数据就会消失,所以需要重新进行请求
//如果没刷新就不用了直接next()
var hasRoles = store && store.getters.roles && store.getters.roles.length > 0;
if(hasRoles){
next();
}else{
//发送请求获取对应的角色信息
try{
var roles = await store.dispatch('GetInfo');//这就是vuex user.js中执行
let rolesName = roles.roles;//得到角色
var accessRoutes = await store.dispatch('GenerateRoutes',rolesName);//这里就是permission.js
router.addRoutes(accessRoutes) //获取完路由的信息就动态添加进去
next({...to})//跳转
}catch(error){
console.log(error)//这里我希望你是打印出来
//因为你是try catch你要不打印报错你就不会看见
//找半天不也不知道原因
next({path:'/login'});//出现错误就不让他进里面看了直接退出登陆。
}
}
}
})
最后说下这token吧,我是放在请求头进行交互的,因为每次都得带着它所以我给他些在了axios的请求拦截中
import axios from 'axios'
var service = axios.create({
baseURL:'http://localhost:9000/',
withCredentials:true,//允许cookie
})
// 请求拦截将头部放入token
service.interceptors.request.use(
config =>{
config.headers['token'] = getToken();//根据刚才说的token存哪从哪取
return config;
},
error =>{
return Promise.reject(error);
}
)