Preface:

Needs: according to the different administrative privileges of users don’t match, both: matching navigation of different operations, particularly in the background management system, if only in the navigation menu will not be display, can still be open page directly through the path, because of its routing information already in the routing information object (new Router ({})) was registered with function

Of course, the global navigation guard can be used to distinguish different users and allow them to enter different paths, but this can only be used for simple permission judgment, and the front-end has been written to death, so the flexibility is not high, and it cannot be customized for each user to distinguish permissions

Project Address:Github.com/cgq001/vue-…

Welcome star, save maybe use, after all, permissions management is very common

Rules to use

1. UI display of dynamic setting permissions

Here we use the element-UI Three tree control with the following data structure:

Data: [{id: 1, the label: '1', children: [{id: 4, label: 'secondary 1-1, children: [{id: 9, label:' level 3 '1-1-1}, {id: 10, label: 'triple the 1-1-2'}}}]], {id: 2, label: 'level 2' children: [{id: 5, label: 'secondary 2-1}, {id: 6, the label: 'secondary 2-2'}}, {id: 3, label: 'level 3' children: [{id: 7, label: 'secondary 3-1}, {id: 8, label:' secondary 3-2}]}]Copy the code

This tree control is selected because its data structure is very close to our registered routing information structure, and it can be perfectly displayed in the Three tree control without modifying the routing information data structure again

2. Extract the routing information object required by side navigation into an array, screen out the corresponding routing information according to the array returned by the background, and add it to the routing information object through addRoutes, then the dynamic addition of routing information can be completed

details

// Create an array routing file in router.js to store all child routes under '/' (all dynamic routes are children of '/')
let routerLists=[ 
  {
    id:1.path: ' '.label: 'home'.redirect: '/index'.// Redirect to
    meta: {title: 'home'.table: true.display: false.icon: 'el-icon-s-home'}}, {id: 2.path: '/index'.name: 'index'.label: 'home'.component: _import('Index/Index'),
    meta: {title: 'home'.table: true.display:true.icon: 'el-icon-s-home'}}, {id: 3.path: '/shop'.name: 'shop'.label: 'Merchandise Management'.component: _import('Shop/Shop'),
    meta: {title: 'List of Goods'.table: true.display:true.icon: 'el-icon-s-operation'}}, {id:20.path: '/admin'.label: 'Administrator List'.component: _import('admin/index'),
    meta: {title: 'Administrator List'.table: true.display:true.icon: 'el-icon-s-custom'
    },
    children:[
      {
        id:21.path: '/admin/index'.label: 'Administrator List'.component: _import('admin/admin'),
        meta: {title: 'Administrator List'.table: true.display:true.icon:'el-icon-tickets'}}, {id:22.path: '/admin/adminlist'.label: 'Add Administrator'.component: _import('admin/adminlist'),
        meta: {title: 'Add Administrator'.table: true.display:true.icon:'el-icon-document-remove'}}]}]// Define the parent route of the array above
let routerAlls=[   // This is the parent route of routerLists
        {
          path: '/'.component: Home
        }
]

1. Permission configuration table// String the routing information object, then remove the Component field and pass it to the permission configuration table
 let routerListString =JSON.stringify(routerLists)
 let src= routerListStr(routerListString)
 store.commit('serRouterList',src)

 let arr=[1.2.3.20.21.22]   // Here is the permission list array (the background according to the user identity of the corresponding route array)

 // Obtain the routing information table of the user according to the permission configuration table (ARR array) and dynamic Routing information object (routerLists array), and add it to the secondary route of the routerAlls route
 
 2.Get dynamic route routerAlls[0].children = routerListFun(arr,routerLists)  
RouterListFun filters dynamic routing information objects (routerLists) based on arR


3.Gets the render menu array for the side navigation bar// Get the menu list of this user based on arR and routerLists
let mentParse =JSON.parse(JSON.stringify(src))
let menuList = routerListFun(arr,mentParse)   // routerListFun removes the Component from the returned array
store.commit('setMents',menuList)   // Add it to vuex


// Register the route
let routers =new Router({
  mode: 'history'.// base: process.env.BASE_URL,
  routes: [{path: '/loading'.name: 'loading'.component: () = > import('.. /views/Load/Loading.vue'),
      meta: {title: 'login'.table: false}}}])// Add the filtered routing information object to the routing table
routers.addRoutes(routerAlls)


// Perform global navigation guard
routers.beforeEach((to,from,next) = >{
    
      if(to.path ! ='/loading') {let username=store.state.load.userList.username
          
          if(username){
            next()
          }else{

            next({
              path:'/loading'.query: {path:to.path
              }
            }) 
          }
      }else{
        next()
      }   
})

export default routers;
Copy the code

The appendix

1. Write rules for dynamic routes

* Route writing rule *1, only level 1 routes (actually level 2 routes) : * {id: 2.//ID must be unique globally
          path: '/index'.// The routing path must be unique globally
          name: 'index'.// Name: the name must be unique globally. If there is a second-level route, the first-level route cannot have a name
          label: 'home'.// page name (used to display name when permissions are configured)
          component: _import('Index/Index'),      // File address (this corresponds to the views directory)
          meta: {title: 'home'.// Page name (horizontal Teble TAB toggle)
            table: true.// Whether to display the Teable toggle button
            display:true.// Whether to display in the side navigation menu
            icon: 'el-icon-s-home'                // Side navigation icon}}2, including level-2 routes (actually level-3 routes) {id:20.//ID must be unique globally
            path: '/admin'.// The routing path must be unique globally (parent).
            label: 'Administrator List'.// page name (used to display name when permissions are configured)
            component: _import('admin/index'),      Note: This file should contain the router-view tag to display sub-pages.
            meta: {title: 'Administrator List'.// Page name (horizontal Teble TAB toggle)
                table: true.display:true.// Whether to display in the side navigation menu (note that this is the parent, if false, the child is not collapsing)
                icon: 'el-icon-s-custom'              // Side navigation icon
            },
            children:[
              {
                id:21.//ID must be unique globally
                path: '/admin/index'.// The routing path must be unique globally (parent).
                label: 'Administrator List'.// page name (used to display name when permissions are configured)
                component: _import('admin/admin'),   // File address (this corresponds to the views directory)
                meta: {title: 'Administrator List'.// Page name (horizontal Teble TAB toggle)
                  table: true.// Whether to display the Teable toggle button
                  display:true.// Whether to display in the side navigation menu
                  icon:'el-icon-tickets'            // Side navigation icon}}}]Copy the code

2. RouterListFun and routerListStr

// Filter the corresponding routing information objects according to the permission array returned by the background
export function routerListFun(arr,allList){


    let arrArray=[]
			
    for(let i=0; i<arr.length; i++){for(let k=0; k<allList.length; k++){if(arr[i] == allList[k].id){
                arrArray.push(allList[k])
            }
        }
    }
    
    
    
    for(let i=0; i<arrArray.length; i++){if(arrArray[i].children && arrArray[i].children.length>0){
            arrArray[i].childrens=[]
            for(let k=0; k<arrArray[i].children.length; k++){for(let j=0; j<arr.length; j++){if(arrArray[i].children[k].id == arr[j]){
                        arrArray[i].childrens.push(arrArray[i].children[k])
                    }
                }
            }
            arrArray[i].children=arrArray[i].childrens
        }
    }
    return arrArray;
}

// Returns the permission list based on the entire routing information object

export function  routerListStr(routerStr){
    
        let routerJson= JSON.parse(routerStr)
        for(let i=0; i<routerJson.length; i++){if(routerJson[i].component){
                routerJson[i].component=' '
            }

            if(routerJson[i].children && routerJson[i].children.length>0) {for(let k=0; k<routerJson[i].children.length; k++){ routerJson[i].children[k].component=' '}}}return routerJson;
}
Copy the code

3. Route rendering

<! RouterList () {routerList () {routerList () {routerList () {
 <div v-for="item in routerList" :key="item.id" >
        <! -- Contains secondary navigation -->
        <el-submenu :index="item.id.toString()" v-if="item.children && item.children.length > 0 && item.meta.display==true">
                        <template slot="title">
                            <i :class="item.meta.icon"></i>
                            <span>{{item.label}}</span>
                        </template>
                <el-menu-item v-show="items.meta.display" v-for="(items,indexs) in item.children" :key="indexs" :index="items.path">
                            <i :class="items.meta.icon"></i>
                            {{items.label}}
                </el-menu-item>
        </el-submenu>
        <! Display :false render secondary navigation as primary navigation -->
       <el-menu-item v-for="(items,indexs) in item.children" :key="indexs" :index="items.path" v-show="items.meta.display"  v-else-if="item.children && item.children.length > 0 && item.meta.display==false" >
                        <i :class="item.meta.icon"></i>
                        <span slot="title">{{item.label}}</span>
         </el-menu-item>
        <! Render level navigation -->
        <el-menu-item  v-show="item.meta.display" :index="item.path"  v-else >
                        <i :class="item.meta.icon"></i>
                        <span slot="title">{{item.label}}</span>
        </el-menu-item>
    </div>
Copy the code