vue学习日记09

路由权限

router.js

import Vue from "vue";
import VueRouter from "vue-router";
import NotFound from "../views/Notfound/404.vue";
import Forbidden from "../views/User/403.vue";
import NProgress from "nprogress";
import findLast from "loadsh/findLast";
import { notification } from "ant-design-vue";
import { check, isLogin } from "../utils/auth";
import "nprogress/nprogress.css";
Vue.use(VueRouter);

const routes = [
  //  User
  {
    path: "/user",
    hideInMenu: true,
    component: () =>
      import(/* webpackChunkName: "user" */ "../layouts/Userlayout.vue"),
    redirect: "/user/login",
    children: [
      {
        path: "/user/login",
        name: "login",
        component: () =>
          import(/* webpackChunkName: "user" */ "../views/User/login")
      },
      {
        path: "user/register",
        name: "register",
        component: () => {
          import(/* webpackChunkName: "user" */ "../views/User/register");
        }
      }
    ]
  },
  //  dashboard
  {
    path: "/",
    meta: { authority: ["user", "admin"] },
    component: () =>
      import(/* webpackChunkName: "layout" */ "../layouts/BasicLayout.vue"),
    children: [
      {
        path: "/dashboard",
        component: { render: h => h("router-view") },
        name: "dashboard",
        meta: { icon: "dashboard", title: "仪表盘" },
        children: [
          {
            path: "/dashboard/analysis",
            name: "analysis",
            meta: { title: "分析页" },
            component: () =>
              import(
                /* webpackChunkName: "dashaboard" */ "../views/Dashaboard/analysis.vue"
              )
          }
        ]
      }
    ]
  },
  // form
  {
    path: "/form",
    name: "form",
    component: () =>
      import(/* webpackChunkName: "layout" */ "../layouts/BasicLayout.vue"),
    redirect: "/form/basic-form",
    meta: { icon: "form", title: "表单", authority: ["admin"] },
    children: [
      {
        path: "/form/basic-form",
        name: "basicform",
        meta: { title: "基础表单" },
        component: () =>
          import(/*webpackChunkName: "form" */ "../views/Forms/BasicForm")
      },
      {
        path: "/form/step-form",
        name: "stepform",
        hideChildrenInMenu: true,
        meta: { title: "分步表单" },
        component: () =>
          import(
            /*webpackChunkName: "form" */ "../views/Forms/StepForm/StepForm.vue"
          ),
        redirect: "/form/step-from/info",
        children: [
          {
            path: "/form/step-from/info",
            name: "info",
            component: () =>
              import(
                /*webpackChunkName: "from"*/ "../views/Forms/StepForm/Info.vue"
              )
          },
          {
            path: "/form/step-from/comfirm",
            name: "comfirm",
            component: () =>
              import(
                /*webpackChunkName: "from"*/ "../views/Forms/StepForm/Comfirm.vue"
              )
          },
          {
            path: "/form/step-from/result",
            name: "result",
            component: () =>
              import(
                /*webpackChunkName: "from"*/ "../views/Forms/StepForm/Result.vue"
              )
          }
        ]
      }
    ]
  },// 404
  {
    path: "*",
    name: "404",
    hideInMenu: true,
    component: NotFound
  },
  //403
  {
    path: "/403",
    name: "403",
    hideInMenu: true,
    component: Forbidden
  }
];
const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes
});

router.beforeEach((to, from, next) => {
  if (to.path !== from.path) {
    NProgress.start();
  }
  const record = findLast(to.matched, record => record.meta.authority);
  if (record && !check(record.meta.authority)) {
    if (!isLogin() && to.path !== "/user/login") {
      next({
        path: "/user/login"
      });
    } else if (to.path !== "/403") {
      notification.error({
        message: "403",
        description: "您没有权限访问该页面,请联系管理员咨询"
      });
      next({
        path: "/403"
      });
    }
    NProgress.done();
  }
  next();
});
router.afterEach(() => {
  NProgress.done();
});
export default router;

siderMenu.vue

<template>
  <div style=" 256px">
    <a-menu
      :selectedKeys="selectedKeys"
      :openKeys.sync="openKeys"
      mode="inline"
      :theme="theme"
    >
      <template v-for="item in menuData">
        <a-menu-item
          v-if="!item.children"
          :key="item.path"
          @click="$router.push({ path: item.key, query: $route.query })"
        >
          <a-icon v-if="item.meta.icon" :type="item.meta.icon" />
          <span>{{ item.meta.title }}</span>
        </a-menu-item>
        <sub-menu v-else :menu-info="item" :key="item.path" />
      </template>
    </a-menu>
  </div>
</template>

<script>
import SubMenu from "./SubMenu";
import { check } from "../utils/auth";
export default {
  components: {
    "sub-menu": SubMenu
  },
  props: {
    theme: {
      type: String,
      default: "dark"
    }
  },
  watch: {
    "$route.path": function(val) {
      this.selectedKeys = this.selectedKeysMap[val];
      this.openKeys = this.collapsed ? [] : this.openKeysMap[val];
    }
  },
  data() {
    this.selectedKeysMap = {};
    this.openKeysMap = {};
    const menuData = this.getMenuData(this.$router.options.routes);
    return {
      collapsed: false,
      menuData,
      selectedKeys: this.selectedKeysMap[this.$route.path],
      openKeys: this.collapsed ? [] : this.openKeysMap[this.$route.path]
    };
  },
  methods: {
    toggleCollapsed() {
      this.collapsed = !this.collapsed;
    },
    getMenuData(routes = [], parentKeys = [], selectedKey) {
      const menuData = [];
      for (let item of routes) {
        if (item.meta && item.meta.authority && !check(item.meta.authority)) {
          continue;
        }
        if (item.name && !item.hideInMenu) {
          this.openKeysMap[item.path] = parentKeys;
          this.selectedKeysMap[item.path] = [selectedKey || item.path];
          const newItem = { ...item };
          delete newItem.children;
          if (item.children && !item.hideChildrenInMenu) {
            newItem.children = this.getMenuData(item.children, [
              ...parentKeys,
              item.path
            ]);
          } else {
            this.getMenuData(
              item.children,
              selectedKey ? parentKeys : [...parentKeys, item.path],
              selectedKey || item.path
            );
          }
          menuData.push(newItem);
        } else if (
          !item.hideInMenu &&
          !item.hideChildrenInMenu &&
          item.children
        ) {
          menuData.push(
            ...this.getMenuData(item.children, [...parentKeys, item.path])
          );
        }
      }
      return menuData;
    }
  }
};
</script>

subMenu.vue

<template functional>
  <a-sub-menu :key="props.menuInfo.path">
    <span slot="title">
      <a-icon
        v-if="props.menuInfo.meta.icon"
        :type="props.menuInfo.meta.icon"
      />
      <span>{{ props.menuInfo.meta.title }}</span>
    </span>
    <template v-for="item in props.menuInfo.children">
      <a-menu-item
        v-if="!item.children"
        :key="item.path"
        @click="
          parent.$router.push({ path: item.path, query: parent.$route.query })
        "
      >
        <a-icon v-if="item.meta.icon" :type="item.meta.icon"></a-icon>
        <span>{{ item.meta.title }}</span>
      </a-menu-item>
      <sub-menu v-else :key="item.path" :menu-info="item" />
    </template>
  </a-sub-menu>
</template>
<script>
export default {
  props: ["menuInfo"]
};
</script>

auth.js

export function getCurrentAuthority() {
  return ["admin"];
}

export function check(authority) {
  const current = getCurrentAuthority();
  return current.some(item => authority.includes(item));
}

export function isLogin() {
  const current = getCurrentAuthority();
  return current && current[0] !== "guest";
}
原文地址:https://www.cnblogs.com/wangnothings/p/12525188.html