Vue-element-admin实现动态路由

Vue-element-admin实现动态路由

一 克隆与安装Vue

此步骤省略,因为都是对Vue-element-admin进行二次开发

二 关于Vue-element-admin内部结构分析

1 静态路由

vue-element-admin是一款开源免费前端后台系统管理框架,clone即用,非常方便,对应它存在的两种路由设计,一种是静态路由,一种是动态路由。
图片说明

这是vue为了提供的静态路由中一些常用页面,比如根目录,登录,404等,如果还需要添加左边栏菜单,可以模仿静态路由的设计里面,还有权限的设计。

2 动态路由

(1)修改/src/store/modules/permission.js 文件

import { asyncRoutes, constantRoutes } from '@/router'
import { getAuthMenu } from '@/api/user'
import Layout from '@/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 (resolve: any) => require([`@/views/${view}.vue`], resolve)
 */
export function generaMenu(routes, data) {
  data.forEach(item => {
    // alert(JSON.stringify(item))
    const menu = {
      path: item.path === '#' ? item.id + '_key' : item.path,
      // component: item.component === '#' ? Layout : () => import(`@/views${item.component}`),
      component: item.component === '#' ? Layout : (resolve) => require([`@/views${item.component}`], resolve),
      hidden: item.hidden,
      redirect: item.redirect,
      children: [],
      name: item.name,
      meta: item.meta
      // meta: { title: item.name, id: item.id, 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 = []
      // 先查询后台并返回左侧菜单数据并把数据添加到路由
      getAuthMenu(state.token).then(response => {
        let data = response
        if (response.code !== 20000) {
          alert(JSON.stringify('菜单数据加载异常'))
          // throw new Error('菜单数据加载异常')
        } else {
          data = response.data
          Object.assign(loadMenuData, data)
          const tempAsyncRoutes = Object.assign([], asyncRoutes)
          // tempAsyncRoutes = asyncRoutes
          generaMenu(tempAsyncRoutes, loadMenuData)
          let accessedRoutes
          if (roles.includes('admin')) {
            // alert(JSON.stringify(asyncRoutes))
            accessedRoutes = tempAsyncRoutes || []
          } else {
            accessedRoutes = filterAsyncRoutes(tempAsyncRoutes, roles)
          }
          commit('SET_ROUTES', accessedRoutes)
          resolve(accessedRoutes)
        }
        // generaMenu(asyncRoutes, data)
      }).catch(error => {
        console.log(error)
      })
    })
  }
}

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

对照一下原版就可以发现更改的部分,这里面一般在编译的时候会出现rang of null的错误,这是因为你的babel-eslint版本过高的原因,因为老外改过打包的底层逻辑。所以我门一劳永逸,直接降低版本:
npm i babel-eslint@7.2.3
* 修改 /src/router/index.js *

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

动态路由只留下这个就行了。不过你之前写过的静态路径也要注释掉。

(3) 添加动态路由的请求方法 /src/api/user.js

export function getAuthMenu() {
  return request({
    url: '/configinfo/getAuthMenu ',
    method: 'post'
  })
}

这里面你需要什么参数可以携带进去,比如权限什么都可能。
(4) 重点就是后端返回的JSON串了

{"code":20000,"data":[{"id":1,"hidden":true,"name":"GSMSystem","path":"/GSMSystem","pid":0,"url":"/GSMSystem","alwaysShow":true,"component":"#","meta":{"icon":"icon","status":true,"title":"GSM后台"},"children":[{"alwaysShow":true,"component":"/GSMSystem/paramOption/index","hidden":false,"id":11,"meta":{"icon":"paramOption","status":true,"title":"参数配置"},"name":"paramOption","path":"GSMSystem/paramOption","pid":30,"url":"GSMSystem/paramOption"},{"alwaysShow":true,"component":"/GSMSystem/logInformation/index","hidden":false,"id":11,"meta":{"icon":"logInformation","status":true,"title":"日志显示"},"name":"logInformation","path":"GSMSystem/logInformation","pid":30,"url":"GSMSystem/logInformation"},{"alwaysShow":true,"component":"/GSMSystem/logInformationQuery/index","hidden":false,"id":11,"meta":{"icon":"logInformationQuery","status":true,"title":"日志查询"},"name":"logInformationQuery","path":"GSMSystem/logInformationQuery","pid":30,"url":"GSMSystem/logInformationQuery"},{"alwaysShow":true,"component":"/GSMSystem/scanRateStatus/index","hidden":false,"id":11,"meta":{"icon":"scanRateStatus","status":true,"title":"扫描状态"},"name":"scanRateStatus","path":"GSMSystem/scanRateStatus","pid":30,"url":"GSMSystem/scanRateStatus"},{"alwaysShow":true,"component":"/GSMSystem/heartLog/index","hidden":false,"id":11,"meta":{"icon":"heartLog","status":true,"title":"GSM心跳显示"},"name":"heartLog","path":"GSMSystem/heartLog","pid":30,"url":"GSMSystem/heartLog"},{"alwaysShow":true,"component":"/GSMSystem/updateData/index","hidden":false,"id":11,"meta":{"icon":"updateData","status":true,"title":"更新程序"},"name":"updateData","path":"GSMSystem/updateData","pid":30,"url":"GSMSystem/updateData"}]},{"id":2,"hidden":true,"name":"hbcdmadisplay","path":"/hbcdmadisplay","pid":1,"url":"/hbcdmadisplay","alwaysShow":true,"component":"#","meta":{"icon":"icon","status":true,"title":"CDMA后台"},"children":[{"alwaysShow":true,"component":"/hbcdmadisplay/index","hidden":false,"id":11,"meta":{"icon":"hbcdmadisplay","status":true,"title":"hbcdmadisplay"},"name":"hbcdmadisplay","path":"/hbcdmadisplay","pid":30,"url":"/hbcdmadisplay"}]},{"id":3,"hidden":false,"name":"interception","path":"/interception","pid":2,"url":"/interception","alwaysShow":true,"component":"#","meta":{"icon":"icon","status":true,"title":"截取任务"},"children":[{"alwaysShow":true,"component":"/interception/taskmanagement/index","hidden":false,"id":11,"meta":{"icon":"taskmanagement","status":true,"title":"任务管理"},"name":"taskmanagement","path":"interception/taskmanagement","pid":30,"url":"interception/taskmanagement"}]}]}

GsomFormat插件可以直接转译成类即可使用


//这是设计好的类,可以直接使用
import java.util.List;

public class RouterMeunInfo {
    public int id;
    public boolean hidden;
    public String name;
    public String path;
    public int pid;
    public String url;
    public boolean alwaysShow;
    public String component;
    //涉及meta内部集合
    public Meta meta;
    //设计chilren
    public List<Children> children;





    public static class Meta{
        public String icon;
        public boolean status;
        public String title;
    }


    public static class Children{
        public boolean alwaysShow;
        public String component;
        public boolean hidden;
        public int id;
        public Meta meta;
        public String name;
        public String path;
        public int pid;
        public String url;

    }
}

至于案列,转译一下json就可以看出来里面的逻辑了。

全部评论

相关推荐

1 收藏 评论
分享
牛客网
牛客企业服务