ant design pro of Vue版本登陆权限
这是原始篇也是最好理解并且根据各自接口需求改方法,总结就是登陆的时候把角色权限id传到permission.js做匹配,然后vuex进行拦截匹配对应菜单结结尾附带路由文件代码。
1.第一步配置接口
注释main.js里mock.js
devServer: {
// development server port 8000
port: 8000,
// If you want to turn on the proxy, please remove the mockjs /src/main.jsL11
proxy: {
'/api': {
target: '接口地址',
changeOrigin: true,
pathRewrite: { '^/api': '' }
}
}
},
配置登陆接口api
接着去登陆页导入接口
代码已贴出可参考
<template>
<div class="main">
<a-form
id="formLogin"
class="user-layout-login"
ref="formLogin"
:form="form"
@submit="handleSubmit"
>
<a-tabs
:activeKey="customActiveKey"
:tabBarStyle="{ textAlign: 'center', borderBottom: 'unset' }"
@change="handleTabClick"
>
<a-tab-pane key="tab1" tab="账号密码登录">
<!--<a-alert v-if="isLoginError" type="error" showIcon style="margin-bottom: 24px;" message="账户或密码错误(admin/ant.design )" />-->
<a-form-item>
<a-input
size="large"
type="text"
placeholder="账户: admin"
v-decorator="[
'username',
{rules: [{ required: true, message: '请输入帐户名或邮箱地址' }, { validator: handleUsernameOrEmail }], validateTrigger: 'change'}
]"
>
<a-icon slot="prefix" type="user" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-item>
<a-form-item>
<a-input
size="large"
type="password"
autocomplete="false"
placeholder="密码: admin or ant.design"
v-decorator="[
'password',
{rules: [{ required: true, message: '请输入密码' }], validateTrigger: 'blur'}
]"
>
<a-icon slot="prefix" type="lock" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-item>
</a-tab-pane>
<a-tab-pane key="tab2" tab="手机号登录">
<a-form-item>
<a-input size="large" type="text" placeholder="手机号" v-decorator="['mobile', {rules: [{ required: true, pattern: /^1[34578]\d{9}$/, message: '请输入正确的手机号' }], validateTrigger: 'change'}]">
<a-icon slot="prefix" type="mobile" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-item>
<a-row :gutter="16">
<a-col class="gutter-row" :span="16">
<a-form-item>
<a-input size="large" type="text" placeholder="验证码" v-decorator="['captcha', {rules: [{ required: true, message: '请输入验证码' }], validateTrigger: 'blur'}]">
<a-icon slot="prefix" type="mail" :style="{ color: 'rgba(0,0,0,.25)' }"/>
</a-input>
</a-form-item>
</a-col>
<a-col class="gutter-row" :span="8">
<a-button
class="getCaptcha"
tabindex="-1"
:disabled="state.smsSendBtn"
@click.stop.prevent="getCaptcha"
v-text="!state.smsSendBtn && '获取验证码' || (state.time+' s')"
></a-button>
</a-col>
</a-row>
</a-tab-pane>
</a-tabs>
<!--<a-form-item>-->
<!--<a-checkbox v-decorator="['rememberMe']">自动登录</a-checkbox>-->
<!--<router-link-->
<!--:to="{ name: 'recover', params: { user: 'aaa'} }"-->
<!--class="forge-password"-->
<!--style="float: right;"-->
<!-->忘记密码</router-link>-->
<!--</a-form-item>-->
<a-form-item style="margin-top:24px">
<a-button
size="large"
type="primary"
htmlType="submit"
class="login-button"
:loading="state.loginBtn"
:disabled="state.loginBtn"
>确定</a-button>
</a-form-item>
<!--<div class="user-login-other">-->
<!--<span>其他登录方式</span>-->
<!--<a>-->
<!--<a-icon class="item-icon" type="alipay-circle"></a-icon>-->
<!--</a>-->
<!--<a>-->
<!--<a-icon class="item-icon" type="taobao-circle"></a-icon>-->
<!--</a>-->
<!--<a>-->
<!--<a-icon class="item-icon" type="weibo-circle"></a-icon>-->
<!--</a>-->
<!--<router-link class="register" :to="{ name: 'register' }">注册账户</router-link>-->
<!--</div>-->
</a-form>
<two-step-captcha
v-if="requiredTwoStepCaptcha"
:visible="stepCaptchaVisible"
@success="stepCaptchaSuccess"
@cancel="stepCaptchaCancel"
></two-step-captcha>
</div>
</template>
<script>
import md5 from 'md5'
import TwoStepCaptcha from '@/components/tools/TwoStepCaptcha'
import { mapActions } from 'vuex'
import { timeFix } from '@/utils/util'
import { rolePrivilege } from '@/api/privilege'
import { login, } from '@/api/login'
export default {
components: {
TwoStepCaptcha
},
data () {
return {
customActiveKey: 'tab1',
loginBtn: false,
// login type: 0 email, 1 username, 2 telephone
loginType: 0,
isLoginError: false,
requiredTwoStepCaptcha: false,
stepCaptchaVisible: false,
form: this.$form.createForm(this),
state: {
time: 60,
loginBtn: false,
// login type: 0 email, 1 username, 2 telephone
loginType: 0,
smsSendBtn: false
}
}
},
created () {
// get2step({ })
// .then(res => {
// this.requiredTwoStepCaptcha = res.result.stepCode
// })
// .catch(() => {
// this.requiredTwoStepCaptcha = false
// })
// this.requiredTwoStepCaptcha = true
},
methods: {
...mapActions(['Login', 'Logout']),
// handler
handleUsernameOrEmail (rule, value, callback) {
const { state } = this
const regex = /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\.[a-zA-Z0-9_-]{2,3}){1,2})$/
if (regex.test(value)) {
state.loginType = 0
} else {
state.loginType = 1
}
callback()
},
handleTabClick (key) {
this.customActiveKey = key
// this.form.resetFields()
},
handleSubmit (e) {
e.preventDefault()
const {
form: { validateFields },
state,
customActiveKey,
Login
} = this
state.loginBtn = true
const validateFieldsKey = customActiveKey === 'tab1' ? ['username', 'password'] : ['mobile', 'captcha']
validateFields(validateFieldsKey, { force: true }, (err, values) => {
if (!err) {
console.log('login form', values)
const loginParams = { ...values }
delete loginParams.username
loginParams[!state.loginType ? 'email' : 'username'] = values.username
loginParams.password = md5(values.password)
login(values)
.then((res) => this.loginSuccess(res))
.catch(err => this.requestFailed(err))
.finally(() => {
state.loginBtn = false
})
} else {
setTimeout(() => {
state.loginBtn = false
}, 600)
}
})
},
getCaptcha (e) {
e.preventDefault()
const { form: { validateFields }, state } = this
validateFields(['mobile'], { force: true }, (err, values) => {
if (!err) {
state.smsSendBtn = true
const interval = window.setInterval(() => {
if (state.time-- <= 0) {
state.time = 60
state.smsSendBtn = false
window.clearInterval(interval)
}
}, 1000)
const hide = this.$message.loading('验证码发送中..', 0)
getSmsCaptcha({ mobile: values.mobile }).then(res => {
setTimeout(hide, 2500)
this.$notification['success']({
message: '提示',
description: '验证码获取成功,您的验证码为:' + res.result.captcha,
duration: 8
})
}).catch(err => {
setTimeout(hide, 1)
clearInterval(interval)
state.time = 60
state.smsSendBtn = false
this.requestFailed(err)
})
}
})
},
stepCaptchaSuccess () {
this.loginSuccess()
},
stepCaptchaCancel () {
this.logout().then(() => {
this.loginBtn = false
this.stepCaptchaVisible = false
})
},
loginSuccess (res) {
console.log(res ,'asd')
// check res.homePage define, set $router.push name res.homePage
// Why not enter onComplete
/*
this.$router.push({ name: 'analysis' }, () => {
console.log('onComplete')
this.$notification.success({
message: '欢迎',
description: `${timeFix()},欢迎回来`
})
})
*/
//这一部分是关键部分
if (res.code===0) {//登陆成功后把信息存到sessionStorage
sessionStorage.setItem('user',JSON.stringify(res.data))
var data={
roleId: res.data.roleId
}
if (res.data.roleId===null) {
//因为我登陆 后超级管理员携带了角色id是null所有做了这个if判断
var role =[
'from',
'table',
'dashboard',
]
sessionStorage.setItem('rolePrivilege', JSON.stringify(role))
}else {
rolePrivilege(data).then(role =>{
//这个是权限树查询接口,登陆后获取到了角色id拿到对应值存到sessionStorage
//然后在permission.js需要role对应权限路由的
// meta: { title: '查询表格', keepAlive: true, permission: [ 'table' ] }
console.log('role',role)
sessionStorage.setItem('rolePrivilege', JSON.stringify(role.data))
})
}
}
this.$router.push({ path: '/' })
// 延迟 1 秒显示欢迎信息
setTimeout(() => {
this.$notification.success({
message: '欢迎',
description: `${timeFix()},欢迎回来`
})
}, 1000)
this.isLoginError = false
},
requestFailed (err) {
this.isLoginError = true
this.$notification['error']({
message: '错误',
description: ((err.response || {}).data || {}).message || '请求出现错误,请稍后再试',
duration: 4
})
}
}
}
</script>
<style lang="less" scoped>
.user-layout-login {
label {
font-size: 14px;
}
.getCaptcha {
display: block;
width: 100%;
height: 40px;
}
.forge-password {
font-size: 14px;
}
button.login-button {
padding: 0 15px;
font-size: 16px;
height: 40px;
width: 100%;
}
.user-login-other {
text-align: left;
margin-top: 24px;
line-height: 22px;
.item-icon {
font-size: 24px;
color: rgba(0, 0, 0, 0.2);
margin-left: 16px;
vertical-align: middle;
cursor: pointer;
transition: color 0.3s;
&:hover {
color: #1890ff;
}
}
.register {
float: right;
}
}
}
</style>
完成登陆页操作后我们需要去permission.js 。更改一些代码
import Vue from 'vue'
import router from './router'
import store from './store'
import NProgress from 'nprogress' // progress bar
import '@/components/NProgress/nprogress.less' // progress bar custom style
import notification from 'ant-design-vue/es/notification'
import { setDocumentTitle, domTitle } from '@/utils/domUtil'
import { ACCESS_TOKEN } from '@/store/mutation-types'
import { rolePrivilege } from '@/api/privilege'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = ['login', 'register', 'registerResult'] // no redirect whitelist
const defaultRoutePath = '/dashboard/workplace'
var a = 1//结尾记住要有a++不然用户信息获取失败会无限请求
router.beforeEach((to, from, next) => {
NProgress.start() // start progress bar
to.meta && (typeof to.meta.title !== 'undefined' && setDocumentTitle(`${to.meta.title} - ${domTitle}`))
var user= JSON.parse(sessionStorage.getItem('user'))
var roless = {
permissionList: JSON.parse(sessionStorage.getItem('rolePrivilege'))
}
if (user !== null && user !== undefined) {
/* has token */
if (to.path === '/user/login') {
next({ path: defaultRoutePath })
NProgress.done()
} else {
if (a<=1) {
console.log(store.getters.roles, 'store.getters.roles')
store.dispatch('GenerateRoutes',roless ).then(() => {
console.log(roless, 'rolessadasda')
// 根据roles权限生成可访问的路由表
// 动态添加可访问路由表
router.addRoutes(store.getters.addRouters)
console.log(store.getters.addRouters, 'aaaastore.getters.roles')
const redirect = decodeURIComponent(from.query.redirect || to.path)
if (to.path === redirect) {
// hack方法 确保addRoutes已完成 ,set the replace: true so the navigation will not leave a history record
next({ ...to, replace: true })
} else {
// 跳转到目的路由
next({ path: redirect })
}
})
.catch(() => {
notification.error({
message: '错误',
description: '请求用户信息失败,请重试'
})
store.dispatch('Logout').then(() => {
next({ path: '/user/login', query: { redirect: to.fullPath } })
})
})
a++
} else {
next()
}
}
} else {
if (whiteList.includes(to.name)) {
// 在免登录白名单,直接进入
next()
} else {
next({ path: '/user/login', query: { redirect: to.fullPath } })
NProgress.done() // if current page is login will not trigger afterEach hook, so manually handle it
}
}
})
router.afterEach(() => {
NProgress.done() // finish progress bar
})
vueX更换接口
需要对vuex里的permission.js做一些改动GenerateRoutes
vuex里permission.js
import { asyncRouterMap, constantRouterMap } from '@/config/router.config'
/**
* 过滤账户是否拥有某一个权限,并将菜单从加载列表移除
*
* @param permission
* @param route
* @returns {boolean}
*/
function hasPermission (permission, route) {
console.log(route, 'route')
console.log(route.meta, 'route.meta')
if (route.meta && route.meta.permission) {
let flag = false
for (let i = 0, len = permission.length; i < len; i++) {
flag = route.meta.permission.includes(permission[i])
if (flag) {
return true
}
}
return false
}
return true
}
/**
* 单账户多角色时,使用该方法可过滤角色不存在的菜单
*
* @param roles
* @param route
* @returns {*}
*/
// eslint-disable-next-line
function hasRole(roles, route) {
if (route.meta && route.meta.roles) {
return route.meta.roles.includes(roles.id)
} else {
return true
}
}
function filterAsyncRouter (routerMap, roles) {
console.log(roles, 'filterAsyncRouterroute')
console.log(routerMap, 'filterAsyncRouterrouterMap')
const accessedRouters = routerMap.filter(route => {
if (hasPermission(roles.permissionList, route)) {
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, roles)
}
return true
}
return false
})
return accessedRouters
}
const permission = {
state: {
routers: constantRouterMap,
addRouters: []
},
mutations: {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers
state.routers = constantRouterMap.concat(routers)
}
},
actions: {
GenerateRoutes ({ commit }, data) {
return new Promise(resolve => {
//const { roles } = data
const roles = data//取消括号不然会拿不到值
const accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
commit('SET_ROUTERS', accessedRouters)
resolve()
})
}
}
}
export default permission
vuex里的user.js
import Vue from 'vue'
import { login, getInfo, logout } from '@/api/login'
import { ACCESS_TOKEN } from '@/store/mutation-types'
import { welcome } from '@/utils/util'
import { rolePrivilege } from '@/api/privilege'
const user = {
state: {
token: '',
name: '',
welcome: '',
avatar: '',
roles: [],
info: {}
},
mutations: {
SET_TOKEN: (state, token) => {
state.token = token
},
SET_NAME: (state, { name, welcome }) => {
state.name = name
state.welcome = welcome
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
SET_ROLES: (state, roles) => {
state.roles = roles
},
SET_INFO: (state, info) => {
state.info = info
}
},
actions: {
// 登录
Login ({ commit }, userInfo) {
return new Promise((resolve, reject) => {
login(userInfo).then(response => {
const result = response.result
Vue.ls.set(ACCESS_TOKEN, result.token, 7 * 24 * 60 * 60 * 1000)
commit('SET_TOKEN', result.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
// // 获取用户信息
// GetInfo ({ commit }) {
// var user = JSON.parse(sessionStorage.getItem('user'))
// return new Promise((resolve, reject) => {
// if (user.roleId === null) {
// console.log(user, 'getinfouser')
// var role = {
// permissionList: [
// 'from',
// 'table',
// 'dashboard',
// ]
// }
// resolve(role)
// reject(new Error('getInfo: roles must be a non-null array !'))
// } else {
// rolePrivilege(user).then(response => {
// const result = response.result
//
// if (result.role && result.role.permissions.length > 0) {
// const role = result.role
// role.permissions = result.role.permissions
// role.permissions.map(per => {
// if (per.actionEntitySet != null && per.actionEntitySet.length > 0) {
// const action = per.actionEntitySet.map(action => { return action.action })
// per.actionList = action
// }
// })
// role.permissionList = role.permissions.map(permission => { return permission.permissionId })
// commit('SET_ROLES', result.role)
// commit('SET_INFO', result)
// } else {
// reject(new Error('getInfo: roles must be a non-null array !'))
// }
//
// commit('SET_NAME', { name: result.name, welcome: welcome() })
// commit('SET_AVATAR', result.avatar)
//
// resolve(response)
// }).catch(error => {
// reject(error)
// })
// }
// // getInfo().then(response => {
// // console.log(response, 'response')
// // const result = response.result
// //
// // if (result.role && result.role.permissions.length > 0) {
// // const role = result.role
// // role.permissions = result.role.permissions
// // role.permissions.map(per => {
// // if (per.actionEntitySet != null && per.actionEntitySet.length > 0) {
// // const action = per.actionEntitySet.map(action => { return action.action })
// // per.actionList = action
// // }
// // })
// // role.permissionList = role.permissions.map(permission => { return permission.permissionId })
// // commit('SET_ROLES', result.role)
// // commit('SET_INFO', result)
// // } else {
// // reject(new Error('getInfo: roles must be a non-null array !'))
// // }
// //
// // commit('SET_NAME', { name: result.name, welcome: welcome() })
// // commit('SET_AVATAR', result.avatar)
// //
// // resolve(response)
// // }).catch(error => {
// // reject(error)
// // })
// })
// },
// 登出
Logout ({ commit, state }) {
return new Promise((resolve) => {
logout(state.token).then(() => {
resolve()
}).catch(() => {
resolve()
}).finally(() => {
commit('SET_TOKEN', '')
commit('SET_ROLES', [])
Vue.ls.remove(ACCESS_TOKEN)
})
})
}
}
}
export default user
可做参考router.config.js动态添加菜单
// eslint-disable-next-linexue
import { UserLayout, BasicLayout, RouteView, BlankLayout, PageView } from '@/layouts'
import { bxAnaalyse } from '@/core/icons'
import { tree } from '@/api/privilege'
const constantRouterComponents = {
// 基础页面 layout 必须引入
BasicLayout: BasicLayout,
BlankLayout: BlankLayout,
RouteView: RouteView,
PageView: PageView,
'403': () => import(/* webpackChunkName: "error" */ '@/views/exception/403'),
'404': () => import(/* webpackChunkName: "error" */ '@/views/exception/404'),
'500': () => import(/* webpackChunkName: "error" */ '@/views/exception/500'),
// 你需要动态引入的页面组件
'首页': () => import('@/views/home/index'),
'部门管理': () => import('@/views/Staff/Department'),
'人员管理': () => import('@/views/Staff/StaffManagement'),
'数据字典': () => import('@/views/SystemSetup/Dictionary'),
'设备核对': () => import('@/views/OperationAnalysis/EquipmentCheck'),
'报警信息': () => import('@/views/OperationAnalysis/DeviceAlarm'),
'用户管理': () => import('@/views/Privilege/UserManage'),
'角色管理': () => import('@/views/Privilege/RoleManage'),
'菜单管理': () => import('@/views/Privilege/MenuManage'),
'学校管理': () => import('@/views/SchoolManage/schoolManage'),
'设备登记表': () => import('@/views/SchoolManage/EquipmentRegistration'),
'通讯参数': () => import('@/views/SchoolManage/CommParameters'),
'项目管理': () => import('@/views/projectManage')
}
// 根级菜单
const rootRouter = {
path: '/',
name: 'home',
component: BasicLayout,
meta: { title: '首页' },
redirect: '/home',
children: []
}
const notFoundRouter = {
path: '*', redirect: '/404', hidden: true
}
export const asyncRouterMap = () => {
return new Promise(resolve => {
tree().then(value => {
// const { result } = value.data
const menuNav = []
const routers = generator(value.data)
rootRouter.children = routers
menuNav.push(rootRouter)
menuNav.push(notFoundRouter)
// var data = [
// {
// path: '/',
// name: 'index',
// component: BasicLayout,
// meta: { title: '首页' },
// children: [
// // 人员管理
// {
// path: '/Staff',
// redirect: '/Staff/Department',
// name: 'Staff',
// component: PageView,
// meta: { title: '人员管理', icon: 'form', permission: [ '17' ] },
// children: [
// {
// path: '/Staff/Department',
// name: '部门管理',
// component: () => import('@/views/Staff/Department'),
// meta: { title: '部门管理', permission: [ '18' ] }
// },
// {
// path: '/Staff/StaffManagement',
// name: '人员管理',
// component: () => import('@/views/Staff/StaffManagement'),
// meta: { title: '人员管理', permission: [ '19' ] }
// }
// ]
// },
// // 系统设置
// {
// path: '/SystemSetup',
// redirect: '/SystemSetup/Dictionary',
// component: PageView,
// meta: { title: '系统设置', icon: 'form', permission: [ 'SystemSetup' ] },
// children: [
// {
// path: '/SystemSetup/Dictionary',
// name: 'Dictionary',
// component: () => import('@/views/SystemSetup/Dictionary'),
// meta: { title: '数据字典', permission: [ 'SystemSetup' ] }
// }
// ]
// },
// // 运维分析
// {
// path: '/OperationAnalysis',
// redirect: '/OperationAnalysis/EquipmentCheck',
// component: PageView,
// meta: { title: '运维分析', icon: 'form', permission: [ 'OperationAnalysis' ] },
// children: [
// {
// path: '/OperationAnalysis/EquipmentCheck',
// name: 'EquipmentCheck',
// component: () => import('@/views/OperationAnalysis/EquipmentCheck'),
// meta: { title: '设备核对', permission: [ 'OperationAnalysis' ] }
// }
// ]
// },
// // 权限管理
// {
// path: '/Privilege',
// name: 'Privilege',
// component: PageView,
// meta: { title: '权限管理', icon: 'bank', permission: [ 'Privilege' ] },
// children: [
// {
// path: '/Privilege/UserManage',
// name: 'UserManage',
// component: () => import('@/views/Privilege/UserManage'),
// meta: { title: '用户管理', icon: 'bank', permission: [ 'Privilege' ] }
// },
// {
// path: '/Privilege/RoleManage',
// name: 'RoleManage',
// component: () => import('@/views/Privilege/RoleManage'),
// meta: { title: '角色管理', icon: 'bank', permission: [ 'Privilege' ] }
// },
// {
// path: '/Privilege/MenuManage',
// name: 'MenuManage',
// component: () => import('@/views/Privilege/MenuManage'),
// meta: { title: '菜单管理', icon: 'bank', permission: [ 'Privilege' ] }
// }
// ]
// },
// // 学校管理
// {
// path: '/school',
// name: 'school',
// component: PageView,
// meta: { title: '学校管理', icon: 'bank', permission: [ 'school' ] },
// children: [
// {
// path: '/school/SchoolManage',
// name: 'SchoolManage',
// component: () => import('@/views/SchoolManage/schoolManage'),
// meta: { title: '学校管理', icon: 'bank', permission: [ 'school' ] }
// },
// {
// path: '/school/EquipmentRegistration',
// name: 'EquipmentRegistration',
// component: () => import('@/views/SchoolManage/EquipmentRegistration'),
// meta: { title: '设备登记表', icon: 'exception', permission: [ 'school' ] }
// },
// {
// path: '/school/CommParameters',
// name: 'CommParameters',
// component: () => import('@/views/SchoolManage/CommParameters'),
// meta: { title: '通讯参数', icon: 'global', permission: [ 'school' ] }
// }
// ]
// },
// // 项目管理
// {
// path: '/projectManage',
// name: 'projectManage',
// component: () => import('@/views/projectManage'),
// meta: { title: '项目管理', icon: 'project', permission: [ 'projectManage' ] }
// }
// ]
// },
// {
// path: '*', redirect: '/404', hidden: true
// }
// ]
resolve(menuNav)
})
})
}
export const generator = (routerMap, parent) => {
return routerMap.map(item => {
const { title, show, hideChildren, hiddenHeaderContent, target, icon } = item.meta || {}
const currentRouter = {
// 如果路由设置了 path,则作为默认 path,否则 路由地址 动态拼接生成如 /dashboard/workplace
path: item.resourcePath || `${parent && parent.path || ''}/${item.key}`,
// 路由名称,建议唯一
name: item.id || item.key || '',
// 该路由对应页面的 组件 :方案1
component: item.parentId === null && item.title !== '项目管理' && item.title !== '首页' ? PageView : constantRouterComponents[item.title],
// 该路由对应页面的 组件 :方案2 (动态加载)
// component: constantRouterComponents[item.component || item.key] || () => import(`@/views/${item.component}`),
// meta: 页面标题, 菜单图标, 页面权限(供指令权限用,可去掉)
meta: { title: item.title, icon: item.icon || undefined, permission: [`${item.id}`] }
}
// 是否设置了隐藏菜单
if (show === false) {
currentRouter.hidden = true
}
// 是否设置了隐藏子菜单
if (hideChildren) {
currentRouter.hideChildrenInMenu = true
}
// 为了防止出现后端返回结果不规范,处理有可能出现拼接出两个 反斜杠
if (!currentRouter.path.startsWith('http')) {
currentRouter.path = currentRouter.path.replace('//', '/')
}
// 重定向
item.redirect && (currentRouter.redirect = item.redirect)
// 是否有子菜单,并递归处理
if (item.children && item.children.length > 0) {
// Recursion
currentRouter.children = generator(item.children, currentRouter)
}
return currentRouter
})
}
/**
* 基础路由
* @type { *[] }
*/
export const constantRouterMap = [
{
path: '/user',
component: UserLayout,
redirect: '/user/login',
hidden: true,
children: [
{
path: 'login',
name: 'login',
component: () => import(/* webpackChunkName: "user" */ '@/views/user/Login')
},
{
path: 'register',
name: 'register',
component: () => import(/* webpackChunkName: "user" */ '@/views/user/Register')
},
{
path: 'register-result',
name: 'registerResult',
component: () => import(/* webpackChunkName: "user" */ '@/views/user/RegisterResult')
},
{
path: 'recover',
name: 'recover',
component: undefined
}
]
},
{
path: '/test',
component: BlankLayout,
redirect: '/test/home',
children: [
{
path: 'home',
name: 'TestHome',
component: () => import('@/views/Home')
}
]
},
{
path: '/404',
component: () => import(/* webpackChunkName: "fail" */ '@/views/exception/404')
}
]
这是我们做的模仿jeecg-boot的菜单界面
成功完成登陆后,可以打印vuex信息