Use vue development of back office systems, in addition to routing and page set up, as well as the main logon permissions and routing guard. Since vue-admin-element back office systems used directly, which has done administrative login privileges, the record is for the better sort out the process for their own projects, as well as subsequent viewing and supplements.
vue-admin-element module Address: https://github.com/PanJiaChen/vue-element-admin
vue-admin-element template Introduction: https://segmentfault.com/a/1190000009275424
About Project Files
Here first introduce the list of related documents to facilitate the subsequent path view (mainly marked red)
├── build // build-related ├── config // configuration-related ├── src // source code │ ├── api // All requests │ ├── assets // theme font and other static resources │ ├── components // global common components │ ├── directive // global Order │ ├── filtres // global filter │ ├── iconsThe // project iconsThe all SVG │ ├── lang // internationalization Language │ ├── mock / / project mock simulation data │ ├── Router // routing │ ├── store // global store management │ ├── styles // global style │ ├──utils // global public method │ ├── vendor // public Vendor │ ├── // View page views │ ├── App.vue // entry page │ ├── main.js // initialization inlet loading assembly │ └── permission.js // rights management ├── static // third-party resources are not packaged │ └── Tinymce // rich text ├── .babelrc // babel-loader configuration ├── eslintrc.js // eslint configuration item ├── .gitignore // git ignore items ├── favicon.ico // favicon icon ├── index.html // html template └── package.json // package.json
1, the first is to log into the system function, is used here vuex management login information and user information
Page path: src / views / login / index
// Log
handleLogin () {
// verification was
this. $ Refs.loginForm.validate (Valid => {
IF (Valid) {
// login methods directed Login src / store / modules / user.js in
this. $ store.dispatch ( 'Login', this.loginForm) .then (() => {
// Direction and routing Home Login to
the this $ router.push ({path:. '/'})
}). the catch (( ) => {
})
} {the else
the console.log ( 'Submit error !!')
return to false
}
})
},
2, manage log on and access to user information
Page path: src / store / modules / user.js
// log
the Login ({} the commit, the userInfo) {
const userInfo.username.trim username = () // The empty
const fd = new FormData () // login parameters
fd.append ( 'username', username)
fd.append ( 'password', userInfo.password)
return new new Promise ((Resolve, Reject) => {
Login (FD) .then (Response => {
const = Data response.data
setToken (data.token) // store token information
commit ( 'SET_TOKEN', data.access_token)
Resolve ()
}). the catch (error => {
// the console.log (. 5)
Reject (error)
})
})
},
// obtain user information
GetInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token).then(response => {
const data = response.data
//获取用户权限并存储roles
if (data.roles && data.roles.length > 0) {
commit('SET_ROLES', data.roles)
} else {
reject('getInfo: roles must be a non-null array !')
}
commit('SET_USERNAME', data.username)
commit('SET_NICKNAME', data.nickname)
resolve(response)
}).catch(error => {
reject(error)
})
})
},
3, intercepted request
Page path: src / utils / request.js
Axios from Import 'Axios'
// Import from QS "QS"
Import {} from the Message 'UI-Element'
Import from Store '../store'
Import getToken to {} from '@ / utils / the auth'
Import} from {apiURL '@ / API / config / IP-config'
// Create instance axios
const = axios.create-Service ({
the baseURL: process.env.BASE_API, // API of the base_url
timeout: 15000 // request time
})
// request interceptor
service.interceptors.request.use (
config => {
IF (getToken to ()) {
// if the token is present, to bring .x-token token information request header in each of their key is defined, with the end negotiation unified
config.headers [ 'X--token'] = getToken to ()
}
return config
},
error =>{
// Do something with request error
// console.log(error) // for debug
Promise.reject(error)
}
)
// respone拦截器
service.interceptors.response.use(
(response) => {
response.data RES = const
IF (res.code) {
// custom status code 1000 is valid, values other special status, may be incorporated to modify their business
IF (res.code! == 1000) {
the Message ({
Message : res.message,
of the type: 'error',
DURATION: 5 * 1000
})
// 50008: illegal token; 50012: other clients logged; 50014: token expired;
// IF (res.code === res.code === || 50012 || 50008 res.code === 50014) {
// MessageBox.confirm (
// 'you have been logged out, you can cancel to stay on this page, or log in again',
/ / 'OK sign out',
// {
// confirmButtonText: 're-login',
// cancelButtonText: 'cancel',
// of the type: 'warning'
// }
// ).then(() => {
// store.dispatch('FedLogOut').then(() => {
// location.reload() // 为了重新实例化vue-router对象 避免bug
// })
// })
// }
return Promise.reject('error')
} else {
return response.data
}
} else {
return response
}
// return response
},
error => {
if (typeof (error.response) !== 'undefined') {
if (error.response.status === 401) {
// MessageBox.alert(error.response.data.message, '提示', {
// confirmButtonText:'re-register',
// type: 'warning'
// })
Message({
message: error.response.data.message,
type: 'info',
duration: 5 * 1000
})
setTimeout(function() {
store.dispatch('FedLogOut').then(() => {
location.reload()// 为了重新实例化vue-router对象 避免bug
})
}, 1000)
// .then(() => {
// })
} else {
Message({
message: error.response.data.message,
type: 'error',
duration: 5 * 1000
})
}
} else {
Message({
message: error.message,
type: 'error',
duration: 5 * 1000
})
}
return Promise.reject(error)
}
)
export default service
4, set up routing
Page path: src / router / index.js
import Vue from 'vue' import Router from 'vue-router' // in development-env not use lazy-loading, because lazy-loading too many pages will cause webpack hot update too slow. so only in production use lazy-loading; // detail: https://panjiachen.github.io/vue-element-admin-site/#/lazy-loading Vue.use(Router) /* Layout */ import Layout from '../views/layout/Layout' /** * hidden: true if `hidden:true` will not show in the sidebar(default is false) * alwaysShow: true if set true, will always show the root menu, whatever its child routes length * if not set alwaysShow, only more than one route under the children * it will becomes nested mode, otherwise not show the root menu * redirect: noredirect if `redirect:noredirect` will no redirct in the breadcrumb * name:'router-name' the name is used by <keep-alive> (must set!!!) * meta : { title: 'title' the name show in submenu and breadcrumb (recommend set) icon: 'svg-name' the icon show in the sidebar, } **/ export const constantRouterMap = [ // 基础-路由设置 { path: '/login', component: () => import('@/views/login/index'), hidden: true }, { path: '/404', component: () => import('@/views/404'), hidden: true }, // { path: '*', redirect: '/404', hidden: true }, { path: '', component: Layout, redirect: 'home', children: [{ path: 'home', component: () => import('@/views/home/index'), name: 'home', meta: { title: '首页', icon: 'table', noCache: true } }] } ] export const asyncRouterMap = [
{
path: '/demo',
component: Layout,
redirect: '/demo/demoChild1',
alwaysShow: true, // will always show the root menu
name: 'Demo',
meta: {
title: '示例',
icon: 'tree',
roles: ['admin','demoRoles']
},
Children: [
{
path: 'demoChild1',
Component: () => Import ( '@ / views / Demo / demoChild1'),
name: 'DemoChild1',
Meta: {
title: 'example a C1'
}
},
{
path: 'demoChild2',
Component: () => Import ( '@ / views / Demo / demoChild2'),
name: 'DemoChild2',
Meta: {
title: 'example C2'
}
}
]
},
{path: '* ', redirect:' / 404 ' , hidden: true} // very important, if dynamic routing, be sure to define the last 404 pages, the page could not be matched to prevent error
]
//重置路由
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRouterMap.concat(asyncRouterMap)
// routes: []
})
const router = createRouter()
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
5, filter routing
If the menu bar is dead then write the front end without considering this step.
But we are doing backstage management system, they usually are under the authority of the logged in user have to show a different menu bar.
So to match the appropriate route is particularly important.
Page path: src / store / permission.js
{asyncRouterMap Import, from constantRouterMap} '@ / Router'
/ **
* asyncRouterMap incorporated with constantRouterMap src / router / index defined
* constantRounterMap: General route based write / login, / 404, etc.
* asyncRouterMap: writing must be configured to route and the management roles
/ **
* matches meta.role determined by the current user rights
* @param roles
* @param route
* /
function the hasPermission (roles, route) {
iF (route.meta && route.meta.roles) {
return roles.some (role => route.meta.roles.indexOf (role)> = 0)
} the else {
return to true
}
}
/ **
* recursive filter asynchronous routing table, in line with the user role privileges returns routing table
* @ asyncRouterMap param
* @param the Roles
* /
function filterAsyncRouter(asyncRouterMap, roles) {
const accessedRouters = asyncRouterMap.filter(route => {
if (hasPermission(roles, 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 (the commit {}, Data) {
return new new Promise (Resolve => {
const} = {Data Roles
the let accessedRouters = []
// herein may be adjusted according to business needs, the present project has admin All rights
IF (roles.indexOf ( 'ADMIN')> = 0) {
accessedRouters = asyncRouterMap
} the else {
accessedRouters = filterAsyncRouter (asyncRouterMap, Roles)
}
the commit ( 'SET_ROUTERS', accessedRouters)
Resolve ()
})
}
}
}
Export default permission
6, routing and routing guard intercepted
After we get the user roles, through router.addRoutes
dynamic routing mount
Page path: src / permission.js
Router from Import './router'
Import from Store './store'
Import from nProgress' nProgress' Progress progress bar //
import 'nprogress / nprogress.css' // Progress progress bar style
import {Message} from' element- ui '
Import} {getToken from' @ / utils / auth 'experience // right
// filter qualifying route - can be adjusted according to their own business - according to the parameter information to make the determination, if eligible, then go to the appropriate page, or go to 404
function the hasPermission (Roles, to) {
IF (roles.indexOf ( 'ADMIN')> = 0) {
return to true // permission ADMIN passed Directly
}
IF (to.meta.roles) {
return roles.some (Role => to.meta.roles.indexOf (Role)> = 0)
} the else {
return to true
}
}
const WhiteList = [ '/ Login', '/ 404 '] // not redirected whitelist
router.beforeEach ((to, from, Next) => {
NProgress.start ()
IF (getToken to ()) {
// routing guard
IF (to.path === '/ Login') {
Next ({path: ' / '})
NProgress.done () // IF Current Page iS Dashboard Will Not Trigger afterEach Hook, SO IT Manually handle
} the else {
IF (store.getters.roles.length === 0) {
// If the permission roles as empty, then retrieve user information, update Roles
store.dispatch ( 'the GetInfo'). the then (RES => {// user information pulling
const = Roles res.data.roles
store.dispatch ( 'generateRoutes', {} Roles ) .then (() => { // the roles access rights generated routing table
router.addRoutes (store.getters.addRouters) // add dynamic routing table accessible
next ({... to, replace: true}) // hack method ensures addRoutes has been completed, The SET Replace: The SO to true Navigation History Record Will Not Leave A
})
.}) the catch ((ERR) => {
Store .dispatch ( 'FedLogOut') the then (() => {.
Message.Error An (ERR || 'the Verification failed, Please Login Again')
Next ({path: '/'})
})
})
} the else {
// If there is already permission, filtered eligible routes, if not, then skip to page 404
// here hasPermission roles is to verify compliance, which is a parameter to the page you want to jump to the route-related information, can be modified according to their business
if (the hasPermission (store.getters.roles, to)) {
Next () //
} the else {
Next ({path: '/ 404', Replace: to true, Query: {noGoBack: to true}})
}
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
next('/login')
NProgress.done()
}
}
})
router.afterEach(() => {
NProgress.done() // 结束Progress
})
At this point, log on vue-admin privileges and basic these, of course, there are many other ways, this is only required for the current project, and then continue to follow a perfect complement.
For more information about vue-admin-element can be found here: vue-admin-element template description: https://segmentfault.com/a/1190000009275424 .