feat: add Multi-level menu

This commit is contained in:
xiaoxian521 2021-05-21 12:55:23 +08:00
parent cd872bea83
commit 010ba1a9e1
21 changed files with 501 additions and 326 deletions

22
.vscode/vue3.0.code-snippets vendored Normal file
View File

@ -0,0 +1,22 @@
{
"Vue3.0快速生成模板": {
"prefix": "Vue3.0",
"body": [
"<template>",
"\t<div>\n",
"\t</div>",
"</template>\n",
"<script lang='ts'>",
"export default {",
"\tsetup(){",
"\t\treturn{\n\n\t\t}",
"\t},",
"}",
"</script>\n",
"<style scoped>\n",
"</style>",
"$2"
],
"description": "Vue3.0"
}
}

View File

@ -66,8 +66,9 @@ export default defineComponent({
children: RouteRecordRaw[] = [],
parent: RouteRecordRaw
) {
const showingChildren = children.filter(item => {
const showingChildren = children.filter((item: any) => {
if (item.hidden) {
// hiddentrue
return false;
} else {
onlyOneChild.value = item;

View File

@ -28,6 +28,7 @@ import {
ElTooltip,
ElDrawer,
ElPagination,
ElAlert,
} from "element-plus";
const components = [
@ -58,6 +59,7 @@ const components = [
ElTooltip,
ElDrawer,
ElPagination,
ElAlert,
];
const plugins = [ElLoading];

View File

@ -30,6 +30,14 @@ export const menusConfig = {
hsflowChart: "流程图",
hsseamless: "无缝滚动",
hscontextmenu: "右键菜单",
hsmenus: "多级菜单",
hsmenu1: "菜单1",
"hsmenu1-1": "菜单1-1",
"hsmenu1-2": "菜单1-2",
"hsmenu1-2-1": "菜单1-2-1",
"hsmenu1-2-2": "菜单1-2-2",
"hsmenu1-3": "菜单1-3",
hsmenu2: "菜单2",
},
},
en: {
@ -54,6 +62,14 @@ export const menusConfig = {
hsflowChart: "Flow Chart",
hsseamless: "Seamless Scroll",
hscontextmenu: "Context Menu",
hsmenus: "MultiLevel Menu",
hsmenu1: "Menu1",
"hsmenu1-1": "Menu1-1",
"hsmenu1-2": "Menu1-2",
"hsmenu1-2-1": "Menu1-2-1",
"hsmenu1-2-2": "Menu1-2-2",
"hsmenu1-3": "Menu1-3",
hsmenu2: "Menu2",
},
},
};

View File

@ -1,335 +1,26 @@
import { createRouter, createWebHashHistory, RouteRecordRaw } from "vue-router";
import Layout from "../layout/index.vue";
import homeRouter from "./modules/home";
import flowChartRouter from "./modules/flowchart";
import editorRouter from "./modules/editor";
import componentsRouter from "./modules/components";
import nestedRouter from "./modules/nested";
import systemRouter from "./modules/system";
import errorRouter from "./modules/error";
import remainingRouter from "./modules/remaining";
import { storageSession } from "../utils/storage";
import { i18n } from "/@/plugins/i18n/index";
const routes: Array<RouteRecordRaw> = [
{
path: "/",
name: "home",
component: Layout,
redirect: "/welcome",
children: [
{
path: "/welcome",
name: "welcome",
component: () =>
import(/* webpackChunkName: "home" */ "../views/welcome.vue"),
meta: {
title: "message.hshome",
showLink: true,
savedPosition: false,
},
},
],
meta: {
icon: "el-icon-s-home",
showLink: true,
savedPosition: false,
},
},
{
path: "/components",
name: "components",
component: Layout,
redirect: "/components/split-pane",
children: [
{
path: "/components/video",
component: () =>
import(
/* webpackChunkName: "components" */ "../views/components/video/index.vue"
),
meta: {
title: "message.hsvideo",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/map",
component: () =>
import(
/* webpackChunkName: "components" */ "../views/components/map/index.vue"
),
meta: {
title: "message.hsmap",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/draggable",
component: () =>
import(
/* webpackChunkName: "components" */ "../views/components/draggable/index.vue"
),
meta: {
title: "message.hsdraggable",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/split-pane",
component: () =>
import(
/* webpackChunkName: "components" */ "../views/components/split-pane/index.vue"
),
meta: {
title: "message.hssplitPane",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/button",
component: () =>
import(
/* webpackChunkName: "components" */ "../views/components/button/index.vue"
),
meta: {
title: "message.hsbutton",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/cropping",
component: () =>
import(
/* webpackChunkName: "components" */ "../views/components/cropping/index.vue"
),
meta: {
title: "message.hscropping",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/countTo",
component: () =>
import(
/* webpackChunkName: "components" */ "../views/components/count-to/index.vue"
),
meta: {
title: "message.hscountTo",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/selector",
component: () =>
import(
/* webpackChunkName: "components" */ "../views/components/selector/index.vue"
),
meta: {
title: "message.hsselector",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/seamlessScroll",
component: () =>
import(
/* webpackChunkName: "components" */ "../views/components/seamless-scroll/index.vue"
),
meta: {
title: "message.hsseamless",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/contextmenu",
component: () =>
import(
/* webpackChunkName: "components" */ "../views/components/contextmenu/index.vue"
),
meta: {
title: "message.hscontextmenu",
showLink: false,
savedPosition: true,
},
},
],
meta: {
icon: "el-icon-menu",
title: "message.hscomponents",
showLink: true,
savedPosition: true,
},
},
{
path: "/flowChart",
name: "flowChart",
component: Layout,
redirect: "/flowChart/index",
children: [
{
path: "/flowChart/index",
component: () =>
import(
/* webpackChunkName: "user" */ "../views/flow-chart/index.vue"
),
meta: {
title: "message.hsflowChart",
showLink: false,
savedPosition: true,
},
},
],
meta: {
icon: "el-icon-set-up",
title: "message.hsflowChart",
showLink: true,
savedPosition: true,
},
},
{
path: "/editor",
name: "editor",
component: Layout,
redirect: "/editor/index",
children: [
{
path: "/editor/index",
component: () =>
import(/* webpackChunkName: "user" */ "../views/editor/index.vue"),
meta: {
// icon: 'el-icon-edit-outline',
title: "message.hseditor",
showLink: false,
savedPosition: true,
},
},
],
meta: {
icon: "el-icon-edit-outline",
title: "message.hseditor",
showLink: true,
savedPosition: true,
},
},
{
path: "/system",
name: "system",
component: Layout,
redirect: "/system/base",
children: [
{
path: "/system/base",
component: () =>
import(/* webpackChunkName: "system" */ "../views/system/user.vue"),
meta: {
// icon: '',
title: "message.hsBaseinfo",
showLink: false,
savedPosition: true,
},
},
{
path: "/system/dict",
component: () =>
import(
/* webpackChunkName: "system" */ "../views/system/dict/index.vue"
),
meta: {
// icon: '',
title: "message.hsDict",
showLink: false,
savedPosition: true,
},
},
],
meta: {
icon: "el-icon-setting",
title: "message.hssysManagement",
showLink: true,
savedPosition: true,
},
},
{
path: "/error",
name: "error",
component: Layout,
redirect: "/error/401",
children: [
{
path: "/error/401",
component: () =>
import(/* webpackChunkName: "error" */ "../views/error/401.vue"),
meta: {
title: "message.hsfourZeroOne",
showLink: false,
savedPosition: true,
},
},
{
path: "/error/404",
component: () =>
import(/* webpackChunkName: "error" */ "../views/error/404.vue"),
meta: {
title: "message.hsfourZeroFour",
showLink: false,
savedPosition: true,
},
},
],
meta: {
icon: "el-icon-position",
title: "message.hserror",
showLink: true,
savedPosition: true,
},
},
{
path: "/login",
name: "login",
component: () =>
import(/* webpackChunkName: "login" */ "../views/login.vue"),
meta: {
title: "message.hslogin",
showLink: false,
},
},
{
path: "/register",
name: "register",
component: () =>
import(/* webpackChunkName: "register" */ "../views/register.vue"),
meta: {
title: "message.hsregister",
showLink: false,
},
},
{
// 找不到路由重定向到404页面
path: "/:pathMatch(.*)",
component: Layout,
redirect: "/error/404",
meta: {
icon: "el-icon-s-home",
title: "message.hshome",
showLink: false,
savedPosition: false,
},
},
{
path: "/redirect",
component: Layout,
children: [
{
path: "/redirect/:path(.*)",
component: () => import("../views/redirect.vue"),
},
],
},
homeRouter,
flowChartRouter,
editorRouter,
componentsRouter,
nestedRouter,
systemRouter,
errorRouter,
...remainingRouter,
];
const router = createRouter({

View File

@ -0,0 +1,108 @@
import Layout from "/@/layout/index.vue";
const componentsRouter = {
path: "/components",
name: "components",
component: Layout,
redirect: "/components/split-pane",
children: [
{
path: "/components/video",
component: () => import("/@/views/components/video/index.vue"),
meta: {
title: "message.hsvideo",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/map",
component: () => import("/@/views/components/map/index.vue"),
meta: {
title: "message.hsmap",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/draggable",
component: () => import("/@/views/components/draggable/index.vue"),
meta: {
title: "message.hsdraggable",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/split-pane",
component: () => import("/@/views/components/split-pane/index.vue"),
meta: {
title: "message.hssplitPane",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/button",
component: () => import("/@/views/components/button/index.vue"),
meta: {
title: "message.hsbutton",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/cropping",
component: () => import("/@/views/components/cropping/index.vue"),
meta: {
title: "message.hscropping",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/countTo",
component: () => import("/@/views/components/count-to/index.vue"),
meta: {
title: "message.hscountTo",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/selector",
component: () => import("/@/views/components/selector/index.vue"),
meta: {
title: "message.hsselector",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/seamlessScroll",
component: () => import("/@/views/components/seamless-scroll/index.vue"),
meta: {
title: "message.hsseamless",
showLink: false,
savedPosition: true,
},
},
{
path: "/components/contextmenu",
component: () => import("/@/views/components/contextmenu/index.vue"),
meta: {
title: "message.hscontextmenu",
showLink: false,
savedPosition: true,
},
},
],
meta: {
icon: "el-icon-menu",
title: "message.hscomponents",
showLink: true,
savedPosition: true,
},
};
export default componentsRouter;

View File

@ -0,0 +1,27 @@
import Layout from "/@/layout/index.vue";
const editorRouter = {
path: "/editor",
name: "editor",
component: Layout,
redirect: "/editor/index",
children: [
{
path: "/editor/index",
component: () => import("/@/views/editor/index.vue"),
meta: {
title: "message.hseditor",
showLink: false,
savedPosition: true,
},
},
],
meta: {
icon: "el-icon-edit-outline",
title: "message.hseditor",
showLink: true,
savedPosition: true,
},
};
export default editorRouter;

View File

@ -0,0 +1,36 @@
import Layout from "/@/layout/index.vue";
const errorRouter = {
path: "/error",
name: "error",
component: Layout,
redirect: "/error/401",
children: [
{
path: "/error/401",
component: () => import("/@/views/error/401.vue"),
meta: {
title: "message.hsfourZeroOne",
showLink: false,
savedPosition: true,
},
},
{
path: "/error/404",
component: () => import("/@/views/error/404.vue"),
meta: {
title: "message.hsfourZeroFour",
showLink: false,
savedPosition: true,
},
},
],
meta: {
icon: "el-icon-position",
title: "message.hserror",
showLink: true,
savedPosition: true,
},
};
export default errorRouter;

View File

@ -0,0 +1,27 @@
import Layout from "/@/layout/index.vue";
const flowChartRouter = {
path: "/flowChart",
name: "flowChart",
component: Layout,
redirect: "/flowChart/index",
children: [
{
path: "/flowChart/index",
component: () => import("/@/views/flow-chart/index.vue"),
meta: {
title: "message.hsflowChart",
showLink: false,
savedPosition: true,
},
},
],
meta: {
icon: "el-icon-set-up",
title: "message.hsflowChart",
showLink: true,
savedPosition: true,
},
};
export default flowChartRouter;

View File

@ -0,0 +1,27 @@
import Layout from "/@/layout/index.vue";
const homeRouter = {
path: "/",
name: "home",
component: Layout,
redirect: "/welcome",
children: [
{
path: "/welcome",
name: "welcome",
component: () => import("/@/views/welcome.vue"),
meta: {
title: "message.hshome",
showLink: true,
savedPosition: false,
},
},
],
meta: {
icon: "el-icon-s-home",
showLink: true,
savedPosition: false,
},
};
export default homeRouter;

View File

@ -0,0 +1,96 @@
import Layout from "/@/layout/index.vue";
const nestedRouter = {
path: "/nested",
component: Layout,
redirect: "/nested/menu1/menu1-1",
name: "Nested",
meta: {
title: "message.hsmenus",
icon: "el-icon-s-data",
showLink: true,
savedPosition: false,
},
children: [
{
path: "menu1",
component: () => import("/@/views/nested/menu1/index.vue"),
name: "Menu1",
meta: {
title: "message.hsmenu1",
showLink: true,
savedPosition: false,
},
redirect: "/nested/menu1/menu1-1",
children: [
{
path: "menu1-1",
component: () => import("/@/views/nested/menu1/menu1-1/index.vue"),
name: "Menu1-1",
meta: {
title: "message.hsmenu1-1",
showLink: true,
savedPosition: false,
},
},
{
path: "menu1-2",
component: () => import("/@/views/nested/menu1/menu1-2/index.vue"),
name: "Menu1-2",
redirect: "/nested/menu1/menu1-2/menu1-2-1",
meta: {
title: "message.hsmenu1-2",
showLink: true,
savedPosition: false,
},
children: [
{
path: "menu1-2-1",
component: () =>
import("/@/views/nested/menu1/menu1-2/menu1-2-1/index.vue"),
name: "Menu1-2-1",
meta: {
title: "message.hsmenu1-2-1",
showLink: true,
savedPosition: false,
},
},
{
path: "menu1-2-2",
component: () =>
import("/@/views/nested/menu1/menu1-2/menu1-2-2/index.vue"),
name: "Menu1-2-2",
meta: {
title: "message.hsmenu1-2-2",
showLink: true,
savedPosition: false,
},
},
],
},
{
path: "menu1-3",
component: () => import("/@/views/nested/menu1/menu1-3/index.vue"),
name: "Menu1-3",
meta: {
title: "message.hsmenu1-3",
showLink: true,
savedPosition: false,
},
},
],
},
{
path: "menu2",
name: "Menu2",
component: () => import("/@/views/nested/menu2/index.vue"),
meta: {
title: "message.hsmenu2",
showLink: true,
savedPosition: false,
},
},
],
};
export default nestedRouter;

View File

@ -0,0 +1,46 @@
import Layout from "/@/layout/index.vue";
const remainingRouter = [
{
path: "/login",
name: "login",
component: () => import("/@/views/login.vue"),
meta: {
title: "message.hslogin",
showLink: false,
},
},
{
path: "/register",
name: "register",
component: () => import("/@/views/register.vue"),
meta: {
title: "message.hsregister",
showLink: false,
},
},
{
// 找不到路由重定向到404页面
path: "/:pathMatch(.*)",
component: Layout,
redirect: "/error/404",
meta: {
icon: "el-icon-s-home",
title: "message.hshome",
showLink: false,
savedPosition: false,
},
},
{
path: "/redirect",
component: Layout,
children: [
{
path: "/redirect/:path(.*)",
component: () => import("/@/views/redirect.vue"),
},
],
},
];
export default remainingRouter;

View File

@ -0,0 +1,36 @@
import Layout from "/@/layout/index.vue";
const systemRouter = {
path: "/system",
name: "system",
component: Layout,
redirect: "/system/base",
children: [
{
path: "/system/base",
component: () => import("/@/views/system/user.vue"),
meta: {
title: "message.hsBaseinfo",
showLink: false,
savedPosition: true,
},
},
{
path: "/system/dict",
component: () => import("/@/views/system/dict/index.vue"),
meta: {
title: "message.hsDict",
showLink: false,
savedPosition: true,
},
},
],
meta: {
icon: "el-icon-setting",
title: "message.hssysManagement",
showLink: true,
savedPosition: true,
},
};
export default systemRouter;

View File

@ -173,6 +173,9 @@
background-color: $subMenuHover;
}
}
.el-submenu__title {
color: $menuText;
}
}
& > .el-menu {
i {

View File

@ -0,0 +1,12 @@
<template>
<div class="app-container">
<p>{{$t('message.hsmenu1')}}</p>
<router-view v-slot="{ Component }">
<transition>
<component :is="Component" />
</transition>
</router-view>
</div>
</template>

View File

@ -0,0 +1,3 @@
<template>
<p style="text-indent:2em">{{$t('message.hsmenu1-1')}}</p>
</template>

View File

@ -0,0 +1,10 @@
<template>
<div>
<p style="text-indent:2em">{{$t('message.hsmenu1-2')}}</p>
<router-view v-slot="{ Component }">
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
</div>
</template>

View File

@ -0,0 +1,3 @@
<template>
<p style="text-indent:4em">{{$t('message.hsmenu1-2-1')}}</p>
</template>

View File

@ -0,0 +1,3 @@
<template>
<p style="text-indent:4em">{{$t('message.hsmenu1-2-2')}}</p>
</template>

View File

@ -0,0 +1,3 @@
<template>
<p style="text-indent:2em">{{$t('message.hsmenu1-3')}}</p>
</template>

View File

@ -0,0 +1,3 @@
<template>
<p class="app-container">{{$t('message.hsmenu2')}}</p>
</template>