vue-element-admin 通过接口动态创建菜单

vue tytrock ⋅ 于 2021-03-09 10:00:45 ⋅ 449 阅读

1、在src/api/user.js下创建获取接口的请求

export function authMenu(data) {
  return request({
    url: '/user/menu',
    method: 'post',
    data
  })
}

接口的返回的数据格式如下:

{
	"code":0,
	"msg":"",
	"data":{
		"menuList":[
			{
        		"menu_name":"一级菜单1",
    			"icon":"el-icon-star-off",
    			"url":"#",
    			"menu_id":1,
    			"children":[
    				{
    					"menu_name":"一级菜单1-1",
    					"icon":"el-icon-star-off",
    					"url":"#",
    					"menu_id":3,
    					"children":[
    						{
    							"menu_name":"一级菜单1-1-1",
    							"icon":"el-icon-star-off",
    							"url":"/path/url",
    							"menu_id":6,
    							"children":null
    						},{
    							"menu_name":"一级菜单1-1-2",
    							"icon":"el-icon-star-off",
    							"url":"/path/url",
    							"menu_id":7,
    							"children":null
    						}
    					]
    				},{
    					"menu_name":"一级菜单1-2",
    					"icon":"el-icon-star-off",
    					"url":"/path/url",
    					"menu_id":4,
    					"children":null
    				}
    			]
    		},
    		{
    			"menu_name":"一级菜单2",
    			"icon":"el-icon-star-off",
    			"url":"#",
    			"menu_id":2,
    			"children":[
    				{
    					"menu_name":"一级菜单2",
    					"icon":"el-icon-star-off",
    					"url":"/path/url",
    					"menu_id":5,
    					"children":null
    				}
    			]
    		}
    	]
    }
}


2、改造文件src/store/modules/permission.js,根据接口返回的数据创建菜单

import { asyncRoutes, constantRoutes } from '@/router'

import { authMenu } from '@/api/user'//【新加入】引入请求
import Layout from '@/layout'//【新加入】引入layout

/**
 * Use meta.role to determine if the current user has permission
 * @param roles
 * @param route
 */
function hasPermission(roles, route) {
  if (route.meta && route.meta.roles) {
    return roles.some(role => route.meta.roles.includes(role))
  } else {
    return true
  }
}


/**
 * 【新加入】后台查询的菜单数据拼装成路由格式的数据
 * @param routes
 */
export function generaMenu(routes, data) {
  data.forEach(item => {
    // alert(JSON.stringify(item))
    const menu = {
      path: item.url === '#' ? item.menu_id + '_key' : item.url,
      component: item.url === '#' ? Layout : () => import('@/views'+item.url),
      // hidden: true,
      children: [],
      name: 'menu_' + item.menu_id,
      meta: { title: item.menu_name, id: item.menu_id, icon: item.icon, roles: ['admin'] }
    }
    if (item.children) {
      generaMenu(menu.children, item.children)
    }
    routes.push(menu)
  })
}

/**
 * Filter asynchronous routing tables by recursion
 * @param routes asyncRoutes
 * @param roles
 */
export function filterAsyncRoutes(routes, roles) {
  const res = []

  routes.forEach(route => {
    const tmp = { ...route }
    if (hasPermission(roles, tmp)) {
      if (tmp.children) {
        tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      res.push(tmp)
    }
  })

  return res
}

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

const mutations = {
  SET_ROUTES: (state, routes) => {
    state.addRoutes = routes
    state.routes = constantRoutes.concat(routes)
  }
}

const actions = {
  generateRoutes({ commit }, roles) {
    return new Promise(resolve => {
        //【新加入】开始
      const loadMenuData = []
      // 先查询后台并返回左侧菜单数据并把数据添加到路由
      authMenu(state.token).then(response => {
        let data = response
        if (response.code !== 0) {
          this.$message({
            message: '菜单数据加载异常',
            type: 0
          })
        } else {
          data = response.data.menuList
          Object.assign(loadMenuData, data)
          generaMenu(asyncRoutes, loadMenuData)
          let accessedRoutes
          console.log(1111111,asyncRoutes)
          if (roles.includes('admin')) {
            // alert(JSON.stringify(asyncRoutes))
            accessedRoutes = asyncRoutes || []
          } else {
            accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
          }
          commit('SET_ROUTES', accessedRoutes)
          resolve(accessedRoutes)
        }
      })
      //【新加入】结束
      /*
      //原代码
      let accessedRoutes
      if (roles.includes('admin')) {
        accessedRoutes = asyncRoutes || []
      } else {
        accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      commit('SET_ROUTES', accessedRoutes)
      resolve(accessedRoutes)
      */
    }).catch(error => {
        console.log(error)
    })
  }
}

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



本帖已被设为精华帖!
回复数量: 0
    暂无评论~~
    • 请注意单词拼写,以及中英文排版,参考此页
    • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`, 更多语法请见这里 Markdown 语法
    • 支持表情,使用方法请见 Emoji 自动补全来咯,可用的 Emoji 请见 :metal: :point_right: Emoji 列表 :star: :sparkles:
    • 上传图片, 支持拖拽和剪切板黏贴上传, 格式限制 - jpg, png, gif
    • 发布框支持本地存储功能,会在内容变更时保存,「提交」按钮点击时清空
    Ctrl+Enter