This is the first day of my participation in the More text Challenge. For details, see more text Challenge
Usually we have routing configured on the front end in vUE projects, but in some projects we may encounter permission control and we are involved in setting up dynamic routing.
There are two types of dynamic route Settings:
(1) Simple role routing Settings: for example, only administrator and common user permissions are involved. Simple role permissions are usually set directly on the front end
(2) Complex route permission Settings, such as OA system and multiple roles. Usually requires the back end to return a list of routes that the front end uses for rendering
1. Simple role routing Settings
(1) Configure the route permission of the project
// router.js import Vue from 'vue' import Router from 'vue-router' import Layout from '@/layout' Vue.use(Router) let asyncRoutes = [ { path: '/permission', component: Layout, redirect: '/permission/page', alwaysShow: true, name: 'Permission', meta: {title: 'Permission', roles: ['admin', 'editor'], children: [{path: 'page', component: () => import('@/views/permission/page'), name: 'PagePermission', meta: { title: 'Page', roles: }}, {path: 'role', component: () => import('@/views/permission/role'), name: 'RolePermission', meta: { title: 'Role', roles: }}]},] let router = new router ({mode: 'history', scrollBehavior: () => ({y: 0 }), routes: asyncRoutes }) export default routerCopy the code
(2) Create a public asyncrouter.js file
// asyncrouter.js // Determine whether the current role has access permissions. route) { if (route.meta && route.meta.roles) { return roles.some(role => route.meta.roles.includes(role)) } else { Return true}} export function filterAsyncRoutes(routes, roles) {const res = []; routes.forEach(route => { const tmp = { ... route } if (hasPermission(roles, tmp)) { if (tmp.children) { tmp.children = filterAsyncRoutes(tmp.children, roles) } res.push(tmp) } }) return res }Copy the code
(3) Create route guard: Create a public permission-js file and set route guard
Import Router from './router' import Store from './store' import NProgress from 'NProgress 'nprogress/nprogress. CSS '// Progress bar style import {getToken} from '@/utils/auth' import {filterAsyncRoutes} from '@/utils/asyncRouter.js' NProgress.configure({ showSpinner: Const whiteList = ['/login'] router.beforeeach (async (to, from, Next) => {// start the progress bar nprogress.start () // get the title in the route meta, Const hasToken = getToken() // Determine whether the current user is logged in. If (hasToken) {if (to.path === '/login') { next({ path: '/'}) NProgress. Done ()} else {/ / retrieve the user role from the store const hasRoles = store. The getters, roles & store. The getters. Roles. The length > 0 If (hasRoles) {next()} else {try {const roles = await store.state.roles Access to the role of the routing table const accessRoutes = filterAsyncRoutes (await store. State. Routers, roles) / / dynamic routing is added to the router router.addRoutes(accessRoutes) next({ ... To, replace: true})} catch (error) {// Delete the user login information and go back to next(' /login? Redirect =${to.path} ') nprogress.done ()}}}} else {// if (whitelist.indexof (to.path)! == -1) {// If the route you want to jump to is a whiteList route, if yes, go to next()} else {// If the route you want to jump to is not a whiteList route, go to next(' /login? Redirect =${to.path} ') // redirect=${to.path} ') // nprogress.done ()}}) router-aftereach (() => {// nprogress.done ()})Copy the code
(4) Import the permission-js file into main.js
(5) Store roles in the store when login
2. Complex routing permission Settings (the back end dynamically returns routing data)
(1) Configure the project route file. There are no routes or some public routes in the file, that is, routes without permission
import Vue from 'vue' import Router from 'vue-router' import Layout from '@/layout'; Vue.use(Router) export const constantRoutes = [{path: '/login', component: () => import('@/views/login'), hidden: true }, { path: '/404', component: () => import('@/views/404'), hidden: true }, ] const createRouter = () => new Router({ mode: 'history', scrollBehavior: () => ({ y: 0 }), routes: constantRoutes }) const router = createRouter() export function resetRouter() { const newRouter = createRouter() router.matcher = newRouter.matcher } export default routerCopy the code
(2) Create a public asyncrouter.js file
Import {constantRoutes} from '.. /router'; // The Layout component is the home page of the project. When switching routes, switch only the Layout component import Layout from '@/ Layout '; Export function getAsyncRoutes(routes) {const res = [] const keys = ['path', 'name', 'children', ForEach (item => {const newItem = {}; Ponent if (item.com) {/ / whether item.com ponent equals' Layout, if is replaced with the introduction of the Layout of the component directly if (item.com ponent = = = 'Layout') { Ponent = Layout} else {newItem.com / / item.com ponent is not equal to 'Layout, then it is a component path address, NewItem.com = resolve => require([' @/views/${item.com} '],resolve) => require([' @/views/${item.com} '],resolve) NewItem.com = (() => import(' @/views/${item.com} ')); }} for (const key in item) {if (keys.includes(key)) {newItem[key] = item[key]}} If (newitem.children && Newitem.children.length) {newitem.children = getAsyncRoutes(item.children)} Res.push (newItem)}) // Return an array of processed and available routes return res}Copy the code
(3) Create route guard: Create a public permission-js file and set route guard
// Router 'import Store from './store' import NProgress from' NProgress '// progress bar import 'nprogress/nprogress.css' // progress bar style import { getToken } from '@/utils/auth' // get token from cookie import { getAsyncRoutes } from '@/utils/asyncRouter' const whiteList = ['/login']; router.beforeEach( async (to, from, next) => { NProgress.start() document.title = to.meta.title; Const hasToken = getToken() if (hasToken) {if (to.path === '/login') {next({path: '/'}) nprogress.done ()} else {// Let route = await store.state.addroutes; const hasRouters = route && route.length>0; If (hasRouters) {next()} else {// If there is no route in the store, you need to obtain the asynchronous route. Try {const accessRoutes = getAsyncRoutes(await store.state.addroutes); // Add the formatted router. AddRoutes (accessRoutes); // Add the formatted router. next({ ... To, replace: true})} catch (error) {// messe.error (' something went wrong ') next(' /login? redirect=${to.path}`) NProgress.done() } } } } else { if (whiteList.indexOf(to.path) ! == -1) { next() } else { next(`/login? redirect=${to.path}`) NProgress.done() } } }) router.afterEach(() => { NProgress.done() })Copy the code
(4) Import the permission-js file into main.js
(5) Store the routing information in the store during login
$store.dispatch("addRoutes", res.router); $store.dispatch("addRoutes", res.router);Copy the code
At this point, the whole dynamic route can pass through, but the page jump and route guard processing are asynchronous, there will be a dynamic route added to redirect to a blank page, this is because when the route executes next(), the data in the router does not exist, at this point, You can refresh the route via window.location.reload()
Format of the route returned by the backend:
routerList = [ { "path": "/other", "component": "Layout", "redirect": "noRedirect", "name": "otherPage", "meta": {} "title" : "test", and "children" : [{" path ":" a ", "component" : "the file/a", "name" : "a", "meta" : {" title ": "A page", "noCache" : "true"}}, {" path ":" b ", "component" : "the file/b", "name" : "b", "meta" : {" title ":" b page ", "noCache" : "true" } }, ] } ]Copy the code
Note: VUE is a single-page application, so some data will be lost as soon as the page is refreshed, so we need to store the data in the Store to the local, so as to ensure that the route will not be lost. How does VUE retain the status information when the page is refreshed
People are lazy, do not want to picture, are their own blog content (dry goods), hope to help everyone
Public number: xiao He growth, The Buddha department more text, are their own once stepped on the pit or is learned
Interested partners welcome to pay attention to me oh, I am: Xiao Xiao Fat. Everybody progress duck together