vue.js动态获取菜单

https://www.jianshu.com/p/917a21e5f5e1

 

需求:用户登录后获取相应的菜单权限,这里已知后台获取的菜单树

这里介绍两种方式:

1、根据从后台获取的路由路径动态注册路由(import到项目),在前端配置菜单权限时需提交路由的路径给后台;
2、前端代码中将所有的路由路径注册好(全部import到项目),由于路由全部注册好了,根据后台返回的菜单显示即可;但这样在地址栏输入路由还是可以访问到,所以前端配置菜单权限时需要给后台提交相应的接口权限,用户登录后没有这个菜单的接口权限则输入地址栏也无权访问,保证正确性。

两种方式的区别:

第一种是通过后台获取菜单之后去注册路由,那么地址栏输入路由就会报404
第二种是全部注册好路由,地址栏输入不会报404,这时候需要控制接口权限

方式一:动态注册路由

loadingRoutes.js

/*
动态注册路由
页面全在views文件夹下
如:
import page1 from './views/page1.vue'
import page2 from './views/page/page2.vue'
*/
export default (name) => () => import(`@/views/${name}.vue`)

menuUtils.js

// 引入注册路由方法
import loadingRoutes from './loadingRoutes' 

export default (routers, data) => {
  //转换服务端菜单数据,拿到自己想要的字段,比如这里的路由路径component (或者其他的key)
  generaMenu(routers, data)
}

function generaMenu(routers, data) {
  if (data) {
    data.forEach((item) => {
      //这里在和后台规定如果是按钮权限component字段为'/' ,权限按钮为弹出框,没有路由
      if (item.path == "/") {
        return false;
      }
      let menu = Object.assign({}, item);
      if (menu.component == "home") {
        menu.component = require("@/views/Home.vue");
        menu = Object.assign({redirect: item.children?item.children[0].path:"/main"}, menu);
      } else {
       // 注册加载相应路由
        menu.component = loadingRoutes (menu.component)
      }
       //有子菜单
      if (item.leaf == "true") {
        menu.children = [];
        generaMenu(menu.children, item.children)
      }
      // 将菜单push进路由
      routers.push(menu)
    })
  }
}

home.vue

 created() {
      //这里没有直接使用this.$router.options.routes,是因为addRoute的路由规则,在这里this.$router.options.routes获取不到
      //另外在开发的时候,可能由于是热部署,也会不断重复的给nodes添加元素,造成导航条有重复的,简单解决,可以设置一个开关
   let isLoadNodes = sessionStorage.getItem('isLoadNodes');
   if (!isLoadNodes) {
     let menuInfo = sessionStorage.getItem('menuInfo');
     if (menuInfo) {
       let data = JSON.parse(window.sessionStorage.getItem('menuInfo'));
       this.nodes.push(...data);
       sessionStorage.setItem('isLoadNodes', 'true')
     } else {
       //this.$api.getMenus({roleId: getCookie('property_roleId')}).then((res) => {
       this.$api.getMenus({roleId: sessionStorage.getItem('property_roleId')}).then((res) => {
         if (this.$util.checkCode(this, res)) {
           this.nodes.push(...res.data);
           sessionStorage.setItem('isLoadNodes', 'true')
         }
       });
     }
   }
 },

routes.js

const router = new Router({
  mode: 'history',
  routes
});
// 引入MenuUtils 
import MenuUtils from '@/scripts/common/MenuUtils'
let data = JSON.parse(window.sessionStorage.getItem('menuInfo'))
if (data) {
  //这里是防止用户手动刷新页面,整个app要重新加载,动态新增的路由,会消失,所以需要重新add一次
  // 或者通过vuex保存菜单,重新赋值  这里不做说明
  let routes = [];
  MenuUtils(routes, data);
  router.addRoutes(routes);
  window.sessionStorage.removeItem('isLoadNodes');
}

方式二:注册好全部路由,后台控制接口访问权限

方式二其实更简单,由于路由全部注册好了,通过后台返回的菜单树进行显示即可,这里不做详细说明。
如果采用vuex保存菜单,注意刷新的时候重新获取菜单。

本篇文章偏向于说明动态获取菜单的思想,有什么不足的地方或疑问欢迎指出来,谢谢大家~



作者:我追求的小世界
链接:https://www.jianshu.com/p/917a21e5f5e1
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

posted @ 2019-03-25 19:04  前端菜鸟教程  阅读(2768)  评论(0编辑  收藏  举报