Vue zero-based development-dynamic menu Vue-Router

Vue zero-based development-dynamic menu Vue-Router

Third party used

  • vue
  • vue-router
  • elementUI

Achieved effect

Get the menu through the server configuration. Here, MOCK is used to simulate the data of the server. The data is as follows. The data is very long. First use the picture to explain the logic, and then finally I post the completed data

The effect in the system is as follows:

Method to realize

The implementation here requires the use of vue-router, the official routing of vue; the role of routing is to help manage each page and enable the page to do different jumps. For example, we use http://localhost:8080/#/, which will jump to On the homepage, http://localhost:8080/#/Login will jump to the login page. This is a normal behavior. This behavior is due to routing management; routing is operated in code and on the interface In fact, you can't see it. For example, our login interface is not on the menu. What can be seen on the interface is displayed through html, so the realization of the dynamic menu here needs to be divided into two steps, one is to configure the routing, and the second is to display on the interface.

Configure routing table

code show as below

import Vue from 'vue'
import Router from 'vue-router'
import Login from '@/views/Login'
import Home from '@/views/Home'
import NotFound from '@/views/404'
import api from '@/http/api'
import store from '@/store'
import Intro from '@/views/Intro/Intro'
import dept from  '@/views/Sys/dept'

Vue.use(Router)

//push 
const originalPush = Router.prototype.push
//push 
Router.prototype.push = function push(location) {
   return originalPush.call(this, location).catch(err => err)
}

// 
const router = new Router({
  routes: [
    {
      path: '/',
      name: ' ',
      component: Home,
      children: [
        { 
          path: '', 
          name: ' ', 
          component: Intro,
          meta: {
            icon: 'fa fa-home fa-lg',
            index: 0
          }
        }, 
        {
          path: '/dept',
          name: 'dept',
          component: dept
        }
      ]
    },
     {
      path: '/login',
      name: 'Login',
      component: Login
    }, 
    {
      path: '/404',
      name: 'NotFound',
      component: NotFound
    }
  ]
})

router.beforeEach((to, from, next) => {
 // 
 // 
  let userName = sessionStorage.getItem('user')
  if (to.path === '/login') {
   // 
    if(userName) {
      next({ path: '/' })
    } else {
      next()
    }
  } else {
    if (!userName) {
     // 
      next({ path: '/login' })
    } else {
     // 
      addDynamicMenuAndRoutes(userName, to, from)
      next()
    }
  }
})

/**
*  
*/
function addDynamicMenuAndRoutes(userName, to, from) {
 
  if(store.state.app.menuRouteLoaded) {
    console.log(' .')
    return
  }
  api.menu.findNavTree({'userName':userName})
  .then(res => {
   // 
    // 
     let dynamicRoutes = addDynamicRoutes(res.data)
     console.log("dynamicRoutes")
     console.log(dynamicRoutes)
   // routes[0] 
     router.options.routes[0].children = router.options.routes[0].children.concat(dynamicRoutes)
     console.log(router.options.routes[0])
     console.log("router.options.routes")
     console.log(router.options.routes[0].children)
     router.addRoutes(router.options.routes)
    // 
     store.commit('menuRouteLoaded', true)
    // , res.data 
     store.commit('setNavTree', res.data)
  }).then(res => {
    api.user.findPermissions({'name':userName}).then(res => {
     // 
      store.commit('setPerms', res.data)
    })
  })
  .catch(function(res) {
  })
}

/**
*  ( ) 
* @param {*} menuList  
* @param {*} routes  ( ) 
*/
function addDynamicRoutes (menuList = [], routes = []) {
 var temp = []
 for (var i = 0; i < menuList.length; i++) {
   if (menuList[i].children && menuList[i].children.length >= 1) {
     temp = temp.concat(menuList[i].children)
   } else if (menuList[i].url &&/\S/.test(menuList[i].url)) {
      menuList[i].url = menuList[i].url.replace(/^\//, '')
     // 
      var route = {
        path: menuList[i].url,
        component: null,
        name: menuList[i].name,
        meta: {
          icon: menuList[i].icon,
          index: menuList[i].id
        }
      }
      try {
       // URL vue vue url 
       // url="sys/user" "@/views/sys/user.vue", 
        let array = menuList[i].url.split('/')
        let url = ''
        for(let i=0; i<array.length; i++) {
          url += array[i].substring(0,1).toUpperCase() + array[i].substring(1) + '/'
        }
        url = url.substring(0, url.length - 1)
        route['component'] = resolve => require([`@/views/${url}`], resolve)
      } catch (e) {}
      routes.push(route)
   }
 }
 if (temp.length >= 1) {
   addDynamicRoutes(temp, routes)
 } else {
   console.log(' ...')
   console.log(routes)
   console.log(' .')
 }
 return routes
}
console.log("befor export default router")
console.log(router)
export default router
 

Interface display

The code is as follows: menu-tree is a custom component

<!--   -->
      <menu-tree v-for="item in navTree" :key="item.id" :menu="item"></menu-tree>