* 在`src\utils`新建`auth.js`模拟获取当前用户权限及验证权限
>auth.js
~~~
const currentAuth = ["admin"];
export { currentAuth };
export function getCurrentAuthority() {
return currentAuth;
}
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";
}
~~~
* 在`router.js meta`中设置用户权限
> router.js
~~~
import Vue from "vue";
import Router from "vue-router";
import NProgress from "nprogress";
import "nprogress/nprogress.css";
import { check, isLogin } from "../utils/auth";
import { notification } from "ant-design-vue";
import findLast from "lodash/findLast";
Vue.use(Router);
const router = new Router({
mode: "history",
base: process.env.BASE_URL,
routes: [
{
path: "/user",
hideInMenu: true,
component: () => import(/* webpackChunkName: "layout" */ "../layouts/UserLayout"),
children: [
{
path: "/user",
redirect: "/user/login"
},
{
path: "/user/login",
name: "login",
component: () => import(/* webpackChunkName: "user" */ "../views/user/Login")
},
{
path: "/user/register",
name: "register",
component: () => import(/* webpackChunkName: "user" */ "../views/user/Register")
}
]
},
{
path: "/",
meta: {
authority: ["user", "admin"]
},
component: () => import(/* webpackChunkName: "layout" */ "../layouts/BasicLayout"),
children: [
// dashboard
{
path: "/",
redirect: "/dashboard/analysis"
},
{
path: "/dashboard",
name: "dashboard",
meta: {
icon: "dashboard",
title: "仪表盘"
},
component: {
render: h => h("router-view")
},
children: [
{
path: "/dashboard/analysis",
name: "analysis",
meta: {
title: "分析页"
},
component: () =>
import(
/* webpackChunkName: "dashboard" */
"../views/Dashboard/Analysis"
)
}
]
},
// form
{
path: "/form",
name: "form",
component: {
render: h => h("router-view")
},
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/Index"
),
children: [
{
path: "/form/step-form",
redirect: "/form/step-form/info"
},
{
path: "/form/step-form/info",
name: "info",
component: () =>
import(
/* webpackChunkName: "form" */
"../views/Forms/StepForm/Step1"
)
},
{
path: "/form/step-form/confirm",
name: "confirm",
component: () =>
import(
/* webpackChunkName: "form" */
"../views/Forms/StepForm/Step2"
)
},
{
path: "/form/step-form/result",
name: "result",
component: () =>
import(
/* webpackChunkName: "form" */
"../views/Forms/StepForm/Step3"
)
}
]
}
]
}
]
},
{
path: "/403",
name: "403",
hideInMenu: true,
component: () => import(/* webpackChunkName: "exception" */ "@/views/Exception/403")
},
{
path: "*",
name: "404",
hideInMenu: true,
component: () => import(/* webpackChunkName: "exception" */ "@/views/Exception/404")
}
]
});
router.beforeEach((to, from, next) => {
NProgress.start();
// const record = to.matched.find(item => {
// return item.meta.authority;
// });
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="width: 256px">
<!-- openKeys(.sync) 当前展开的 SubMenu 菜单项 key 数组 -->
<!-- selectedKeys(v-model) 当前选中的菜单项 key 数组 -->
<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.path, 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>
/*
* recommend SubMenu.vue https://github.com/vueComponent/ant-design-vue/blob/master/components/menu/demo/SubMenu.vue
* SubMenu1.vue https://github.com/vueComponent/ant-design-vue/blob/master/components/menu/demo/SubMenu1.vue
* */
import SubMenu from "./SubMenu";
import { check } from "../utils/auth";
export default {
props: {
theme: {
type: String,
default: "dark",
},
collapsed: {
type: Boolean,
default: false,
},
},
components: {
"sub-menu": SubMenu,
},
watch: {
"$route.path": function (val) {
this.selectedKeys = this.selectedKeysMap[val];
this.openKeys = this.collapsed ? [] : this.openKeysMap[val];
},
collapsed(val) {
if (val) {
this.cacheOpenKeys = this.openKeys;
this.openKeys = [];
} else {
this.openKeys = this.cacheOpenKeys;
}
},
},
data() {
this.selectedKeysMap = {};
this.openKeysMap = {};
const menuData = this.getMenuData(this.$router.options.routes);
return {
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) {
console.log(item);
if (item.meta && item.meta.authority && !check(item.meta.authority)) {
console.log(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])
);
}
}
console.log(menuData);
return menuData;
},
},
};
</script>
~~~