This includes only page permissions, not component or button level permissions…

Source code: github.com/HYzihong/vu…

Several kinds of schemes

For the backend return optional permission scheme:

  • Plan1 (branch:plan1): a table that returns whether the route name is accessible, for example:{page1:true,page2:true,page3:false}
  • Plan2 (branch:plan2): Returns the permission level, for example:['admin','admin-delete','page1-all']We can match roles in the meta of the routing table
  • Plan3 (branch:plan3): returns the complete routing table, for example:{[{path: "/",name: "Home",component: 'Home',},}, cannot return the absolute path, return Home

The code below is fully functional commented

Scenario 1: The backend returns a table of names of routes that the user can access

The code is SRC /router/index

.import basicsRoutes from "./module/basicsRoutes";
import { setTitle } from ".. /utils/router";
import store from ".. /store";

Vue.use(VueRouter);

const router = new VueRouter({
  mode: "history".base: process.env.BASE_URL,
  basicsRoutes,
});

router.beforeEach((to, from, next) = > {
  to.meta && setTitle(to.meta.title);

  let token = "...";
  if (token) {
    if(! store.state.router.hasGetRules) {// store
      // .dispatch("authorization")
      // .then((rules) => {
      
      // Here is the permission table of the route name returned by the backend
      const rules = { Form: true.List: false.About: true };
      // Generate the complete routing table in store
      store
        .dispatch("concatRoutes", rules)
        .then((routers) = > {
        // Merge the routing tablerouter.addRoutes(routers); next({ ... to,replace: true });
        })
        .catch(() = > {
          next({ name: "login" });
        });
      // })
      // .catch(() => {
      // token = '';
      // next({ name: "login" });
      // });
    } else{ next(); }}else {
    if (to.name === "login") next();
    else next({ name: "login"}); }});export default router;


Copy the code

src/store/module/router


// Route with permission
import asyncRoutes from ".. /.. /router/module/asyncRoutes";
// Basic routing
import basicsRoutes from ".. /.. /router/module/basicsRoutes";

const state = {
  routers: basicsRoutes,// If [] is here, it's ok
  hasGetRules: false};const mutations = {
  CONCAT_ROUTES(state, routerList) {
    // Note the routing table before and after
    state.routers = routerList.concat(basicsRoutes);
    state.hasGetRules = true; }};const getAccesRouterList = (basicsRoutes, rules) = > {
  return basicsRoutes.filter((item) = > {
    if (rules[item.name]) {
    // Recurse if there are child routes
      if (item.children)
        item.children = getAccesRouterList(item.children, rules);
      return true;
    } else return false;
  });
};

const actions = {
  concatRoutes({ commit }, rules) {
    console.log(rules);
    return new Promise((resolve, reject) = > {
      try {
        let routerList = [];
        // console.log(Object.entries(rules));
        /* ["Form", true] ["List", false] ["About", false] */
        // If all pages are accessible, return all routes directly
        if (Object.entries(rules).every((item) = > item[1])) {
          routerList = asyncRoutes;
        } else {
          // Recurse asyncRoutes to see which pages are allowed to access
          routerList = getAccesRouterList(asyncRoutes, rules);
        }
        commit("CONCAT_ROUTES", routerList);
        resolve(state.routers);
      } catch(err) { reject(err); }}); }};export default {
  state,
  mutations,
  actions,
};

Copy the code

Solution 2: The backend returns the permission level of the user

The code is SRC /router/index

./ / omit other code, the code is shown in detail github:https://github.com/HYzihong/vue2-router-permissions
router.beforeEach((to, from, next) = > {
  to.meta && setTitle(to.meta.title);

  let token = "...";
  if (token) {
    if(! store.state.router.hasGetRules) {// store
      // .dispatch("authorization")
      // .then((rules) => {
      const rules = ["about"]; // The user's permission level is passed in
      store
        .dispatch("concatRoutes", rules)
        .then((routers) = > {
          console.log(JSON.stringify(routers)); router.addRoutes(routers); next({ ... to,replace: true });
        })
        .catch(() = > {
          next({ name: "login" });
        });
      // })
      // .catch(() => {
      // token = '';
      // next({ name: "login" });
      // });
    } else{ next(); }}else {
    if (to.name === "login") next();
    else next({ name: "login"}); }});Copy the code

src/store/module/router

./ / omit other code, the code is shown in detail github:https://github.com/HYzihong/vue2-router-permissions

const isRoleTrue = (role, rules) = > {
	// Determine whether the role in the meta of the route contains this permission.
  return role.filter((_role) = > rules.indexOf(_role) > -1).length > 0;
};

const getAccesRouterList = (basicsRoutes, rules) = > {
  return basicsRoutes.filter((item) = > {
    if (isRoleTrue(item.meta.role, rules)) {
    // Recurse if there are child routes
      if (item.children)
        item.children = getAccesRouterList(item.children, rules);
      return true;
    } else return false;
  });
};

const actions = {
  concatRoutes({ commit }, rules) {
    return new Promise((resolve, reject) = > {
      try {
        let routerList = [];
        // If you have the admin permission, return all routes directly
        if (rules.indexOf("admin") > -1) {
          routerList = asyncRoutes;
        } else {
          // Recurse asyncRoutes to see if there is permission to access it
          routerList = getAccesRouterList(asyncRoutes, rules);
        }
        commit("CONCAT_ROUTES", routerList);
        resolve(state.routers);
      } catch(err) { reject(err); }}); }};Copy the code

Scenario 3: The backend returns all routing tables accessible to the user

The code is SRC /router/index




router.beforeEach((to, from, next) = > {
  to.meta && setTitle(to.meta.title);

  let token = "...";
  if (token) {
    if(! store.state.router.hasGetRules) {// store
      // .dispatch("authorization")
      // .then((rules) => {
      store
        .dispatch("concatRoutes")
        .then((routers) = > {
          console.log(routers); router.addRoutes(routers); next({ ... to,replace: true });
        })
        .catch(() = > {
          next({ name: "login" });
        });
      // })
      // .catch(() => {
      // token = '';
      // next({ name: "login" });
      // });
    } else{ next(); }}else {
    if (to.name === "login") next();
    else next({ name: "login"}); }});Copy the code

src/store/module/router



import ajaxRouter from ".. /.. /utils/ajaxRouter";
import routerMap from ".. /.. /utils/routerMap";

// Option 1: use a simple view structure
const returnView = (url) = > {
  return () = > import(`.. /.. /views/${url}.vue`);
};
const initRoute = (router) = > {
  router.component = returnView(router.component);
  if (router.children) getAccesRouterList(router.children);
  return router;
};

// Option 2: Use a complex view structure
const initRoute = (router) = > {
  router.component = routerMap[router.component];
  if (router.children) getAccesRouterList(router.children);
  return router;
};

const getAccesRouterList = (ajaxRouter) = > {
  return ajaxRouter.map((item) = > initRoute(item));
};

const actions = {
  concatRoutes({ commit }) {
    return new Promise((resolve, reject) = > {
      try {
        let routerList = [];
        routerList = getAccesRouterList(ajaxRouter);
        commit("CONCAT_ROUTES", routerList);
        console.log(routerList);
        resolve(state.routers);
      } catch(err) { reject(err); }}); }};Copy the code

src/utils/ajaxRouter


// Simulate the routing table returned by the backend
const ajaxRouter = [
  {
    path: "/form".name: "Form".component: "Form"}, {path: "/about".name: "About".component: "About".children: [{path: "aboutChild".name: "AboutChild".component: "AboutChild",},],}, {path: "/list".name: "List".component: "List",},];export default ajaxRouter;


Copy the code

src/utils/routerMap.js


// The corresponding view file
import Form from ".. /views/Form.vue";
import About from ".. /views/About.vue";
import AboutChild from ".. /views/AboutChild.vue";
import List from ".. /views/List.vue";
const routerMap = {
  Form: Form,
  About: About,
  List: List,
  AboutChild: AboutChild,
};
export default routerMap;

Copy the code

Ps: Before the interview will summarize their own vUE knowledge points, summed up, we can help correct errors, suggestions, common progress ~