vue路由菜单权限设置就button权限设置

路由权限的设计思路:

首先,我们的需要校验权限的路由的 url,全部由后端返回,后端会返回当前用户的路由树数组。
前端在进入页面前请求接口,把数据拿到:

其次,前端会维护一个路由映射组件的列表,如果路由中拿到 url, 匹配到了对应的组件,那么将该组件添加到路由对象中去,相当于,前端路由都是动态生成的。

前端拿到这个路由树数组后,进行递归遍历,将路由树里的一级菜单、二级菜单,寻找对应的组件。

// main.js
const vm = new Vue({
  router,
  store,
  i18n,
  render: h => h(App),
  beforeCreate() {
    getMenu();  // 进入系统前,请求接口
  }
}).$mount("#app");

// 请求后台接口函数,拿到菜单数据和按钮权限数组,
export const getMenu = async () => {
  const req: any = {};
  return new Promise(resolve => {
    Http.get(Url.base.getMenu, req).then((response: AxiosResponse) => {
      let result = response.data;
      if (result.code === Code.SUCCESS) {
        let resultMap = {};
        let menu = result.data.menuInfoMapList;  // 拿到菜单 url 的 list map
        let permission = result.data.operateMapList;  // 拿到按钮权限数据的数组
        let formatedRoutes = formatRoutes(menu);  // 递归菜单,格式化后的菜单树,
        let formatedPermission = formatPermission(permission);  // 权限数组
        resultMap = {
          formatedRoutes,
          formatedPermission
        };
        router.addRoutes(formatedRoutes);  // 利用 vue-router 的 addRoutes 方法,将格式化后的代码添加到路由对象中
        store.commit("base/saveMenu", formatedRoutes);  // 将格式化的菜单树放入状态管理中保存。
        store.commit("setPermission", formatedPermission);  // 将格式化的权限数组也放入状态管理中保存
        resolve(resultMap);
      } else {
        resolve([]);
      }
    });
  });
};

/**
 * 格式化菜单数据为 vue-router 路由对象格式
 */
export const formatRoutes = (menu: any) => {
  if (!menu) {
    return [];
  }
  let result = menu.map((item: any) => {
    let children = [];
    if (item.child) {
      children = formatRoutes(item.child);  // 递归遍历权限树
    }
    return {
      path: item.url || "/layout",  // 如果没有 url, 做一个容错处理,避免路由没有 path
      component: lazyload(item.url),  // loayload 是一个方法,传入 url 作为键,返回 url 对应的组件引用。
      meta: {
        title: item.name
      },
      children: children
    };
  });
  return result;
};

前端拿到的数据大致为:
data: {
  menuInfoMapList: [
     {
         url: "/fruits",
         name: "水果",
         child: [
             {
                  url: "/fruits/apple",   // 二级菜单
                  name: "苹果"
              } ,
              {
                  url: "/fruits/banana",   // 二级菜单
                  name: "香蕉"
              } 
         ]
     }
  ],
  operateMapList: [
     "/eatApple",    // 按钮权限 code
    "/eatBanana"   // 按钮权限 code
  ] 
}


// 下面就是 loazload.ts 文件,维护了后台传来的 url, 和页面编写好的 组件位置。导出一个函数,就是上面的 loazload 函数。
const routes: any = {
  // ===== 权限管理 =====
  "/friuts": () => import("@/layout/Layout.vue"),  // 一级菜单的 url 和组件
  "/friuts/apple": () => import("@/views/Apple.vue"),  // 二级菜单的 url 和组件
  "/friuts/banana": () => import("@/views/Banana.vue"),  // 二级菜单的 url 和组件
};
export default (path: any) => routes[path];



// 下面是按钮权限的控制,比较简单,就是把按钮的  code) 传入校验函数,校验函数就是判断 按钮的 url 在没有在 后台返回的 url 列表中。
export function authHelper(authCode: string) {
  let isExist = store.getters["getPermissionList"].includes(authCode);
  return isExist;
}

// 页面组件上,通过 权限 code 控制按钮权限
<Button  v-if="$authHelper("/eatApple")" @click="handleEat">苹果</Button>

 

posted @ 2019-09-05 18:47  黄code  阅读(2382)  评论(0编辑  收藏  举报