Use the vue-element-admin framework to dynamically obtain the menu function from the backend

Use the vue-element-admin framework to dynamically obtain the menu function from the backend

2. Detailed explanation

The overall idea is: login > get menu based on user information after success > generate routing information based on menu

2.1. Add asyncRoutes routing

Add asyncRoutes array in the vue-router path src\router\index.js to store the routing information corresponding to the menu obtained by the backend.

export const asyncRoutes = [
  { path: '*', redirect: '/404', hidden: true }
] 

The difference between constantRoutes and asyncRoutes

constantRoutes: Routes that do not require dynamic authority determination, such as login pages, 404 pages, and other general pages.

asyncRoutes: requires dynamic authority judgment and dynamically added pages through addRoutes

2.2. Create a new permission.js file

Create a new permission.js file under the vuex path src\store\modules\permission.js . This operation is the most important step, mainly to query the menu from the backend and generate routes.

import { asyncRoutes, constantRoutes } from '@/router'
import { fetchUserMenuList } from '@/api/user'
import Layout from '@/layout'

/**
 * Static route lazy loading * @param view format must start with xxx/xxx without slash * @returns 
 */
export const loadView = (view) => {
  return (resolve) => require([`@/views/${view}.vue`], resolve)
}

/**
 * Assemble the menu data queried from the backend into routing format data* @param routes
 * @param data menu data returned by the backend */
export function generaMenu(routes, data) {
  data.forEach(item => {
    const menu = {
      path: item.url, 
      component: item.component === '#' ? Layout : loadView(item.component), 
      hidden: item.status === 0, // hidden redirect with status 0: item.redirect,
      children: [],
      name: item.code,
      meta: item.meta
    }

    if (item.children) {
      generaMenu(menu.children, item.children)
    }
    routes.push(menu)
  })
  return routes
}

const state = {
  routes: [],
  addRoutes: []
}

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    // Concatenate static routes and dynamic routes state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit }, token) {
    return new Promise(resolve => {
      // Get the user menu from the backend through token and add it to the global state fetchUserMenuList(token).then(res => {
        const menuData = Object.assign([], res.data)
        const tempAsyncRoutes = Object.assign([], asyncRoutes)
        const accessedRoutes = generaMenu(tempAsyncRoutes, menuData)

        commit('SET_ROUTES', accessedRoutes)
        resolve(accessedRoutes)
      }).catch(error => {
        console.log(error)
      })
    })
  }
}

export default {
  namespaced: true,
  state,
  mutations,
  actions
}

2.3. Register the permission module in vuex

If you are using vue-element-admin, please skip this step because it automatically registers all modules under src\store\modules in src\store\index.js . If you are using vue-element-template, you can refer to admin and modify the index.js file, or you can import it manually.

import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'

Vue.use(Vuex)

// https://webpack.js.org/guides/dependency-management/#requirecontext
const modulesFiles = require.context('./modules', true, /\.js$/)

// you do not need `import app from './modules/app'`
// it will auto require all vuex modules from modules file
const modules = modulesFiles.keys().reduce((modules, modulePath) => {
  // set './app.js' => 'app'
  const moduleName = modulePath.replace(/^\.\/(.*)\.\w+$/, '$1')
  const value = modulesFiles(modulePath)
  modules[moduleName] = value.default
  return modules
}, {})

const store = new Vuex.Store({
  modules,
  getters
})

export default store

2.4. Add routing status in getters

Add menuRoutes state in vuex path src\store\getters.js

menusRoutes: state => state.permission.routes 

2.5. Modify the source of menu generation data

Modify the routes data source in the path src\layout\components\Sidebar\index.vue The original data source is routing, and it is changed to be obtained from vuex.

routes() {
      // return this.$router.options.routes
      return this.$store.getters.menusRoutes
    }, 

​At this point, the logic from getting menu data from the backend to page display has been completed. Now let's start calling it after logging in.

2.6. Get the menu after logging in

In the login method of the vuex path src\store\modules\user.js , add the logic of generating routing by obtaining the menu through token after successful login.

 // Get the menu. When calling actions in other files, you must add { root: true }
          dispatch('permission/generateRoutes', data, { root: true }).then((accessRoutes) => {
            router.addRoutes(accessRoutes)
          }) 

2.7. Solve the problem of page blank after refresh

​The above content can already realize the function of displaying the left menu after logging in, but you will find that the page will become blank every time you refresh the page. This is because when the page is refreshed, the vue instance will be reloaded, and the data in the vuex store will be reassigned, causing the routing information in vuex to be cleared.

Add the code for retrieving routes in src\permission.js .

const accessRoutes = await store.dispatch('permission/generateRoutes', store.getters.token)
          router.addRoutes(accessRoutes)
          next({ ...to, replace: true })

3. Summary

​So far, the dynamic acquisition of menu content based on user information has been completed.

This is the end of this article about using the vue-element-admin framework to dynamically obtain menus from the backend. For more relevant vue-element-admin dynamic menu acquisition content, please search for previous articles on 123WORDPRESS.COM or continue to browse the following related articles. I hope everyone will support 123WORDPRESS.COM in the future!

You may also be interested in:
  • Vue dynamic addition of routing and generation of menu method example
  • Vue-router example code for dynamically generating navigation menus based on backend permissions
  • How to dynamically generate submenus in the Vue sidebar
  • How does Vue get data from the background to generate a dynamic menu list

<<:  Detailed explanation of mysql permissions and indexes

>>:  Example of how to install kong gateway in docker

Recommend

Mysql slow query optimization method and optimization principle

1. For comparison of date size, the date format p...

How to publish a locally built docker image to dockerhub

Today we will introduce how to publish the local ...

MySQL master-slave synchronization principle and application

Table of contents 1. Master-slave synchronization...

Vue custom component implements two-way binding

Scenario: The interaction methods between parent ...

CSS3 achieves conic-gradient effect

grammar: background-image: conic-gradient(from an...

How to compile and install opencv under ubuntu

Easy installation of opencv2: conda install --cha...

How to use CSS to achieve two columns fixed in the middle and adaptive

1. Use absolute positioning and margin The princi...

CSS code to achieve 10 modern layouts

Preface I watched web.dev's 2020 three-day li...

Explanation of MySQL index types Normal, Unique and Full Text

MySQL's index types include normal index, uni...

Understanding and application of JavaScript ES6 destructuring operator

Table of contents Preface The role of deconstruct...

Summary of MySQL's commonly used concatenation statements

Preface: In MySQL, the CONCAT() function is used ...

Analysis of the solution to Nginx Session sharing problem

This article mainly introduces the solution to th...

What is the function and writing order of the a tag pseudo class

The role of the a tag pseudo-class: ":link&qu...

W3C Tutorial (6): W3C CSS Activities

A style sheet describes how a document should be ...