Home  >  Article  >  Web Front-end  >  addRoutes implements dynamic permission routing menu

addRoutes implements dynamic permission routing menu

不言
不言Original
2018-07-09 14:36:172737browse

This article mainly introduces the implementation of dynamic permission routing menu by addRoutes. It has certain reference value. Now I share it with everyone. Friends in need can refer to it.

Requirements

Recently taken over A background management system needs to realize the effect of pulling the navigation menu from the background; the navigation menus pulled out are different according to the different permissions of the logged-in user, and the operable interfaces are also different.

Problem

Because the background management system is prepared to use the combination of vue vue-router element-ui vuex, but the single-page application has instantiated vue-router before entering the page. And it is injected into the vue instance, so there is no way to re-customize the route when entering the login page. After a lot of searching, I found that vue-router provided the addRoutes method to add routes in version 2.0, and a glimmer of hope appeared.
After a lot of hard work, the function was finally realized. I recorded it for easy review. I also hope it can help comrades who have the same needs.

Ideas

1. First configure fixed routing addresses locally, such as login and 404 pages, as follows:

import Vue from 'vue'
import Router from 'vue-router'
import store from '@/vuex/store'
Vue.use(Router)

let router = new Router({
  routes: [
    {
      path: '/login',
      name: 'login',
      meta: {requireAuth: false},
      // 模块使用异步加载
      component: (resolve) => require(['../components/login/login.vue'], resolve)
    }]
})
// 拦截登录,token验证
router.beforeEach((to, from, next) => {
  if (to.meta.requireAuth === undefined) {
    if (store.state.token) {
      next()
    } else {
      next({
        path: '/login'
      })
    }
  } else {
    next()
  }
})
export default router

After configuring these fixed routes Only then can we get to the login page, otherwise we will not be able to continue.

2. Then the important step is to agree with the back-end veteran on the permission menu list information that needs to be returned; first, let’s analyze the routing structure we need. Here I take my own routing as an example. . If I directly define the route myself, it will have the following structure:

let router = new Router({
  routes: [
    {
      path: '/login',
      name: 'login',
      meta: {requireAuth: false},
      component: (resolve) => require(['../components/login/login.vue'], resolve)
    },
    {
        path: '/',
        redirect: '/layout'
    },
    {
        path: '/layout',
        component: (resolve) => require(['../layout.vue'], resolve),
        children: [
            {
                path: 'index', 
                meta: {
                    type: '1',       //控制是否显示隐藏 1显示,2隐藏
                    code: 00010001,  // 后面需要控制路由高亮
                    title: '首页',    // 菜单名称
                    permissonList: [] // 权限列表
                }
                component: (resolve) => require(['@/components/index/index.vue'], resolve)
            },
            {
            ...
            }      
        ]
    }]
})

According to the above structural analysis, in fact, the route that really needs to be dynamically configured is actually the children part under /layout, so the backend needs to be returned to us containing An array of all routes is enough

addRoutes implements dynamic permission routing menu

The rootList in the returned data is a list of first-level navigation. The first-level navigation actually has no routing function and is only used to switch the second-level navigation. The menu trigger and subList are the routing information we really need.
3. After getting the permission routing information, we need to process the data locally and assemble it into the data we need:

// 登录
      login () {
        let params = {
          account: this.loginForm.username,
          password: encrypt(this.loginForm.password)
        }
        this.loading = true
        this.$http.post(this.$bumng + '/login', this.$HP(params))
          .then((res) => {
            this.loging = false
            console.info('菜单列表:', res)
            if (res.resultCode === this.$state_ok) {
              // 合并一级菜单和二级菜单,便于显示
              let menus = handleMenu.mergeSubInRoot(res.rootList, res.subList)
              // 本地化处理好的菜单列表
              this.saveRes({label: 'menuList', value: menus})
              // 根据subList处理路由
              let routes = handleMenu.mergeRoutes(res.subList)
              // 本地化subList,便于在刷新页面的时候重新配置路由
              this.saveRes({label: 'subList', value: res.subList})
              // 防止重复配置相同路由
              if (this.$router.options.routes.length  {
            this.loging = false
            console.error('错误:', err)
          })
      },

Methods for processing menu lists and subLists: mergeSubInRoot and mergeRoutes

const routes = [
  {
    path: '/',
    redirect: '/layout'
  },
  {
    path: '/layout',
    component: (resolve) => require(['../layout.vue'], resolve),
    children: []
  }
]
export default {
  /**
   * 合并主菜单和子菜单
   * @param: rootList [Array] 主菜单列表
   * @param: subList [Array] 子菜单
   * */
  mergeSubInRoot (roots, subs) {
    if (roots && subs) {
      for (let i = 0; i  require([`@/components/${subs[i].component}.vue`], resolve),
          meta: {
            type: subs[i].type,
            code: subs[i].code,
            title: subs[i].name,
            permissionList: subs[i].permissionList
          }
        }
        routes[1].children.push(temp)
      }
    }
    return routes
  }
}

So far we have successfully configured permission routing into local routing. My system login is as follows

addRoutes implements dynamic permission routing menu

Follow-up optimization

1. Display of menu list And secondary navigation switching:

<template>
    <p>
      <el-menu>
        <el-menu-item>
          <i></i>
          <span>{{item.name}}</span>
        </el-menu-item>
      </el-menu>
    </p>
</template>

<script>
  import {mapState, mapMutations} from &#39;vuex&#39;
  export default {
    name: &#39;menu&#39;,
    data () {
      return {
        msg: &#39;Welcome to Your Vue.js App&#39;
      }
    },
    computed: {
      ...mapState([&#39;menuList&#39;]),
      activeCode () {
          // 通过code保证在切换字路由的情况下一级路由也是高亮显示
        return this.$route.meta.code.substring(0, 4)
      }
    },
    methods: {
      ...mapMutations([&#39;saveRes&#39;]),
      // 切换二级路由
      switchSubMenu (route) {
        console.info(&#39;路由:&#39;, route)
        if (route.actUrl !== &#39;index&#39;) {
          // 用currentSubMenu控制二级路由数据  
          this.saveRes({label: &#39;currentSubMenu&#39;, value: route.children})
          this.$router.push(`/layout/${route.children[0].actUrl}`)
        } else {
          // 不存在二级路由隐藏二级 
          this.saveRes({label: &#39;currentSubMenu&#39;, value: &#39;&#39;})
          this.$router.push(`/layout/${route.actUrl}`)
        }
      }
    },
    filters: {
      splitCode (code) {
        return code.substring(0, 4)
      }
    }
  }
</script>

2. Prevent the loss of refresh routes; since the single-page application will be re-initialized during refresh, all configured routes will be lost at this time. Once returned to before liberation, only the local The configured route can be jumped. At this time, we can execute the following code in app.vue (ps: no matter where the refresh is performed, app.vue will be executed):

<script>
  import {decrypt} from &#39;@/libs/AES&#39;
  import handleMenu from &#39;@/router/handleMenu&#39;
  export default {
    name: &#39;app&#39;,
    created () {
      // 当this.$router.options.routes的长度为1,且本地缓存存在菜单列表的时候才重新配置路由
      if (this.$router.options.routes.length <= 1 && sessionStorage.getItem(&#39;subList&#39;)) {
        let subList = JSON.parse(decrypt(sessionStorage.getItem(&#39;subList&#39;)))
        let routes = handleMenu.mergeRoutes(subList)
        this.$router.addRoutes(routes)
        // this.$router不是响应式的,所以手动将路由元注入路由对象
        this.$router.options.routes.push(routes)
      }
    }
  }
</script>

In this way, even if refreshed, the routing will be reconfigured.
3. Regarding page button level control, you can customize a command to do this. Because we have put the permission list into the meta object of the corresponding route, we can easily go back to the permissions that the current user has on the current page on each page

addRoutes implements dynamic permission routing menu

Conclusion

After calling it a day, thanks to the addRoutes method added to vue-router2

The above is the entire content of this article. I hope it will be helpful to everyone’s study. For more related content, please Follow PHP Chinese website!

Related recommendations:

Implementation of Vue dynamic routing (pass the route in the background, get it in the front end and generate the sidebar)

##Passing parameters through the params of the Vue attribute $route

The above is the detailed content of addRoutes implements dynamic permission routing menu. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn