feat: 递归菜单
This commit is contained in:
parent
e882fb6055
commit
913d213737
@ -1,2 +1,4 @@
|
|||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
. "${0%/*}/h"
|
. "$(dirname -- "$0")/husky.sh"
|
||||||
|
|
||||||
|
npx --no-install commitlint --edit $1
|
||||||
@ -1,2 +1,5 @@
|
|||||||
#!/usr/bin/env sh
|
#!/bin/sh
|
||||||
. "${0%/*}/h"
|
|
||||||
|
. "$(dirname "$0")/husky.sh"
|
||||||
|
|
||||||
|
npm run lint-staged
|
||||||
1
src/icons/common.svg
Normal file
1
src/icons/common.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1713016089982" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="32457" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M108.8 454.4c-25.6 0-44.8-12.8-44.8-44.8V108.8c0-32 12.8-44.8 44.8-44.8h307.2c25.6 0 38.4 19.2 38.4 44.8v307.2c0 25.6-19.2 38.4-38.4 38.4H108.8z m499.2 0c-25.6 0-38.4-19.2-38.4-44.8V108.8c0-25.6 12.8-44.8 38.4-44.8h307.2c32 0 44.8 12.8 44.8 44.8v307.2c0 25.6-19.2 38.4-44.8 38.4H608zM108.8 960c-32 0-44.8-12.8-44.8-44.8V608c0-25.6 19.2-38.4 44.8-38.4h307.2c25.6 0 38.4 19.2 38.4 38.4v307.2c0 25.6-19.2 44.8-38.4 44.8H108.8z m499.2 0c-25.6 0-38.4-19.2-38.4-44.8V608c0-25.6 19.2-38.4 38.4-38.4h307.2c25.6 0 44.8 19.2 44.8 38.4v307.2c0 25.6-19.2 44.8-44.8 44.8H608z" p-id="32458" fill="#e5e6eb"></path></svg>
|
||||||
|
After Width: | Height: | Size: 939 B |
1
src/icons/form.svg
Normal file
1
src/icons/form.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M0 0m349.090909 0l325.818182 0q349.090909 0 349.090909 349.090909l0 325.818182q0 349.090909-349.090909 349.090909l-325.818182 0q-349.090909 0-349.090909-349.090909l0-325.818182q0-349.090909 349.090909-349.090909Z" fill="#F7A647" /><path d="M663.272727 244.363636a46.545455 46.545455 0 0 1 46.545455 46.545455v84.026182L465.501091 619.264a64 64 0 0 0-2.024727 88.389818l2.024727 2.117818a64 64 0 0 0 88.389818 2.024728l2.117818-2.024728L709.818182 555.950545V733.090909a46.545455 46.545455 0 0 1-46.545455 46.545455H279.272727a46.545455 46.545455 0 0 1-46.545454-46.545455V290.909091a46.545455 46.545455 0 0 1 46.545454-46.545455h384z m108.101818 160.046546a29.090909 29.090909 0 0 1 0.93091 39.633454l-1.44291 1.512728-238.545454 232.727272a29.090909 29.090909 0 0 1-42.065455-40.145454l1.431273-1.512727 238.545455-232.727273a29.090909 29.090909 0 0 1 41.134545 0.512zM401.454545 581.818182H314.181818l-1.745454 0.058182A23.272727 23.272727 0 0 0 314.181818 628.363636h87.272727l1.745455-0.058181A23.272727 23.272727 0 0 0 401.454545 581.818182z m64-110.545455H314.181818l-1.745454 0.058182A23.272727 23.272727 0 0 0 314.181818 517.818182h151.272727l1.745455-0.058182A23.272727 23.272727 0 0 0 465.454545 471.272727z m58.181819-116.363636H314.181818l-1.745454 0.058182A23.272727 23.272727 0 0 0 314.181818 401.454545h209.454546l1.745454-0.058181A23.272727 23.272727 0 0 0 523.636364 354.909091z" fill="#FFFFFF" /></svg>
|
||||||
|
After Width: | Height: | Size: 1.6 KiB |
1
src/icons/home.svg
Normal file
1
src/icons/home.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M1024 512c0 282.7776-229.2224 512-512 512S0 794.7776 0 512 229.2224 0 512 0s512 229.2224 512 512z" fill="#2962FF" /><path d="M493.5936 234.9056a39.3984 39.3984 0 0 1 36.608 0l1.9584 1.024 1.6384 1.536 243.7376 224.512a45.4144 45.4144 0 0 1 13.7344 49.024 36.8896 36.8896 0 0 1-35.6096 23.168H704V716.8a51.2 51.2 0 0 1-51.2 51.2h-76.8v-115.2a64 64 0 0 0-128 0v115.2h-76.8a51.2 51.2 0 0 1-51.2-51.2V534.1696h-54.2336a36.6336 36.6336 0 0 1-33.024-23.552 44.9536 44.9536 0 0 1 13.9136-48.896l244.992-225.792z" fill="#FFFFFF" /></svg>
|
||||||
|
After Width: | Height: | Size: 796 B |
1
src/icons/set.svg
Normal file
1
src/icons/set.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M0 0m349.090909 0l325.818182 0q349.090909 0 349.090909 349.090909l0 325.818182q0 349.090909-349.090909 349.090909l-325.818182 0q-349.090909 0-349.090909-349.090909l0-325.818182q0-349.090909 349.090909-349.090909Z" fill="#62A8FC" /><path d="M704.570182 266.554182l-90.216727 90.88 75.892363 77.533091 90.391273-91.054546c20.957091 51.688727 10.973091 113.384727-30.161455 155.403637-45.300364 46.277818-113.757091 53.480727-166.946909 22.830545l-38.458182 42.914909-28.066909 31.325091-183.970909 205.312a42.286545 42.286545 0 0 1-60.706909 0l-15.185454-15.511273a44.532364 44.532364 0 0 1 0-62.033454l209.559272-179.293091-139.182545-142.545455-43.938909-0.023272-50.850909-83.549091 40.96-41.902546 83.642182 52.282182 0.581818 43.985455 140.776727 144.384 40.96-35.048728c-40.029091-55.773091-35.863273-134.295273 13.498182-184.715636a137.402182 137.402182 0 0 1 151.424-31.173818zM651.636364 570.181818c64.267636 0 116.363636 52.096 116.363636 116.363637s-52.096 116.363636-116.363636 116.363636-116.363636-52.096-116.363637-116.363636 52.096-116.363636 116.363637-116.363637zM277.178182 746.007273c-8.378182 8.576-8.378182 22.458182 0 31.034182 8.378182 8.564364 21.969455 8.564364 30.370909 0 8.378182-8.564364 8.378182-22.458182 0-31.022546a21.154909 21.154909 0 0 0-30.370909 0z m364.765091-122.496a14.545455 14.545455 0 0 0-14.475637 13.067636l-0.069818 1.477818v74.053818l0.058182 1.396364a14.545455 14.545455 0 0 0 12.986182 13.067636l1.501091 0.081455h61.707636l1.396364-0.069818a14.545455 14.545455 0 0 0 13.067636-12.986182l0.081455-1.489455-0.069819-1.396363a14.545455 14.545455 0 0 0-12.986181-13.079273l-1.489455-0.069818h-47.173818v-59.508364l-0.058182-1.396363a14.545455 14.545455 0 0 0-14.475636-13.149091z" fill="#FFFFFF" /></svg>
|
||||||
|
After Width: | Height: | Size: 2.0 KiB |
1
src/icons/switch.svg
Normal file
1
src/icons/switch.svg
Normal file
@ -0,0 +1 @@
|
|||||||
|
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg class="icon" width="200px" height="200.00px" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"><path d="M0 0m349.090909 0l325.818182 0q349.090909 0 349.090909 349.090909l0 325.818182q0 349.090909-349.090909 349.090909l-325.818182 0q-349.090909 0-349.090909-349.090909l0-325.818182q0-349.090909 349.090909-349.090909Z" fill="#3271FD" /><path d="M718.661818 232.727273a22.341818 22.341818 0 0 1 22.283637 20.677818l0.058181 1.664 0.011637 328.145454a61.463273 61.463273 0 0 1 0 114.501819l-0.011637 71.214545a22.341818 22.341818 0 0 1-44.625454 1.664l-0.058182-1.664v-71.214545a61.463273 61.463273 0 0 1 0-114.501819v-328.145454c0-12.334545 10.007273-22.341818 22.341818-22.341818z m-424.494545 0a22.341818 22.341818 0 0 1 22.283636 20.677818l0.058182 1.664v328.145454a61.463273 61.463273 0 0 1 0 114.501819v71.214545a22.341818 22.341818 0 0 1-44.625455 1.664l-0.058181-1.664-0.011637-71.214545a61.463273 61.463273 0 0 1 0-114.501819l0.011637-328.145454c0-12.334545 10.007273-22.341818 22.341818-22.341818z m212.247272 0a22.341818 22.341818 0 0 1 22.283637 20.677818l0.058182 1.664v81.221818a83.816727 83.816727 0 0 1 0 161.512727v271.127273a22.341818 22.341818 0 0 1-44.625455 1.664l-0.058182-1.664v-271.127273a83.816727 83.816727 0 0 1 0-161.512727v-81.221818c0-12.334545 10.007273-22.341818 22.341818-22.341818z" fill="#FFFFFF" /></svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
@ -5,29 +5,19 @@
|
|||||||
<span class="logo_title" v-if="!collapsed">dc admin</span>
|
<span class="logo_title" v-if="!collapsed">dc admin</span>
|
||||||
</div>
|
</div>
|
||||||
<a-layout-sider :collapsed="collapsed" breakpoint="xl" class="layout_side" :width="220">
|
<a-layout-sider :collapsed="collapsed" breakpoint="xl" class="layout_side" :width="220">
|
||||||
<a-scrollbar style="height: 100%; overflow: auto" outer-class="scrollbar">
|
<a-scrollbar style="height: 100%; overflow: auto" outer-class="scrollbar"><Menu /></a-scrollbar>
|
||||||
<a-menu show-collapse-button breakpoint="xl" @collapse="onCollapse">
|
|
||||||
<a-menu-item key="0_0_0" data-obj="1">Menu 1</a-menu-item>
|
|
||||||
<a-sub-menu :key="item" v-for="item in 20">
|
|
||||||
<template #icon><icon-apps></icon-apps></template>
|
|
||||||
<template #title>Navigation 1</template>
|
|
||||||
<a-menu-item key="0_0">Menu 1</a-menu-item>
|
|
||||||
<a-menu-item key="0_1">Menu 2</a-menu-item>
|
|
||||||
<a-menu-item key="0_2" disabled>Menu 3</a-menu-item>
|
|
||||||
</a-sub-menu>
|
|
||||||
</a-menu>
|
|
||||||
</a-scrollbar>
|
|
||||||
</a-layout-sider>
|
</a-layout-sider>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Logo from "@/assets/img/logo.jpg";
|
import Logo from "@/assets/img/logo.jpg";
|
||||||
|
import Menu from "@/layout/components/Menu/index.vue";
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
|
import { useThemeConfig } from "@/store/theme-config";
|
||||||
|
|
||||||
const collapsed = ref<boolean>(false);
|
const themeStore = useThemeConfig();
|
||||||
const onCollapse = (type: boolean) => {
|
const { collapsed } = storeToRefs(themeStore);
|
||||||
collapsed.value = type;
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@ -2,9 +2,10 @@
|
|||||||
<a-layout-header class="header">
|
<a-layout-header class="header">
|
||||||
<div class="header_crumb">
|
<div class="header_crumb">
|
||||||
<div class="menu_fold">
|
<div class="menu_fold">
|
||||||
<a-button size="mini" type="text" class="menu_fold_icon">
|
<a-button size="mini" type="text" class="menu_fold_icon" @click="onCollapsed">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<icon-menu-fold :size="18" />
|
<icon-menu-fold :size="18" v-if="!collapsed" />
|
||||||
|
<icon-menu-unfold :size="18" v-if="collapsed" />
|
||||||
</template>
|
</template>
|
||||||
</a-button>
|
</a-button>
|
||||||
</div>
|
</div>
|
||||||
@ -114,11 +115,19 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import Notice from "@/layout/components/Header/components/Notice/index.vue";
|
import Notice from "@/layout/components/Header/components/Notice/index.vue";
|
||||||
import myImage from "@/assets/img/my-image.jpg";
|
import myImage from "@/assets/img/my-image.jpg";
|
||||||
|
import pinia from "@/store/index";
|
||||||
import { Modal } from "@arco-design/web-vue";
|
import { Modal } from "@arco-design/web-vue";
|
||||||
import { useRouter } from "vue-router";
|
import { useRouter } from "vue-router";
|
||||||
import pinia from "@/store/index";
|
import { storeToRefs } from "pinia";
|
||||||
import { useUserInfoStore } from "@/store/user-info";
|
import { useUserInfoStore } from "@/store/user-info";
|
||||||
|
import { useThemeConfig } from "@/store/theme-config";
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
const themeStore = useThemeConfig();
|
||||||
|
const { collapsed } = storeToRefs(themeStore);
|
||||||
|
|
||||||
|
const onCollapsed = () => {
|
||||||
|
themeStore.setCollapsed(!collapsed.value);
|
||||||
|
};
|
||||||
|
|
||||||
const logOut = () => {
|
const logOut = () => {
|
||||||
Modal.warning({
|
Modal.warning({
|
||||||
|
|||||||
@ -1,7 +1,21 @@
|
|||||||
<template>
|
<template>
|
||||||
<div></div>
|
<a-menu breakpoint="xl" :collapsed="collapsed">
|
||||||
|
<MenuItem :route-tree="routeTree" />
|
||||||
|
</a-menu>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts"></script>
|
<script setup lang="ts">
|
||||||
|
import MenuItem from "@/layout/components/Menu/menu-item.vue";
|
||||||
|
import { storeToRefs } from "pinia";
|
||||||
|
import { useRoutesListStore } from "@/store/route-list";
|
||||||
|
import { useThemeConfig } from "@/store/theme-config";
|
||||||
|
|
||||||
|
const routerStore = useRoutesListStore();
|
||||||
|
const { routeTree } = storeToRefs(routerStore);
|
||||||
|
const themeStore = useThemeConfig();
|
||||||
|
const { collapsed } = storeToRefs(themeStore);
|
||||||
|
|
||||||
|
console.log("路由树", routeTree.value);
|
||||||
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped></style>
|
<style lang="scss" scoped></style>
|
||||||
|
|||||||
26
src/layout/components/Menu/menu-item.vue
Normal file
26
src/layout/components/Menu/menu-item.vue
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<template>
|
||||||
|
<template v-for="item in props.routeTree" :key="item.name">
|
||||||
|
<a-sub-menu v-if="item.children && item.children.length > 0" :key="item.name">
|
||||||
|
<template #icon><SvgIcon :name="item.meta.icon" :size="25" /></template>
|
||||||
|
<template #title>{{ item.meta.title }}</template>
|
||||||
|
<MenuItem :route-tree="item.children" />
|
||||||
|
</a-sub-menu>
|
||||||
|
<a-menu-item v-else :key="item.name">
|
||||||
|
<template #icon><SvgIcon :name="item.meta.icon" :size="25" /></template>
|
||||||
|
<div>{{ item.meta.title }}</div>
|
||||||
|
</a-menu-item>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
defineOptions({ name: "MenuItem" });
|
||||||
|
// 通过defineProps接收父组件的值
|
||||||
|
const props = defineProps({
|
||||||
|
routeTree: {
|
||||||
|
type: Array,
|
||||||
|
default: () => []
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped></style>
|
||||||
@ -5,10 +5,6 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { useRoute } from "vue-router";
|
|
||||||
const route = useRoute();
|
|
||||||
console.log("页面查看路由", route);
|
|
||||||
|
|
||||||
// 引入组件-异步组件
|
// 引入组件-异步组件
|
||||||
const layouts = {
|
const layouts = {
|
||||||
defaults: defineAsyncComponent(() => import("@/layout/LayoutDefaults/index.vue")),
|
defaults: defineAsyncComponent(() => import("@/layout/LayoutDefaults/index.vue")),
|
||||||
|
|||||||
19
src/store/theme-config.ts
Normal file
19
src/store/theme-config.ts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import { defineStore } from "pinia";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 全局配置
|
||||||
|
* @methods setCollapsed 设置菜单折叠
|
||||||
|
*/
|
||||||
|
export const useThemeConfig = defineStore("themeConfig", {
|
||||||
|
state: (): any => ({
|
||||||
|
collapsed: false // 是否折叠菜单
|
||||||
|
}),
|
||||||
|
actions: {
|
||||||
|
async setCollapsed(data: boolean) {
|
||||||
|
this.collapsed = data;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
persist: {
|
||||||
|
enabled: true
|
||||||
|
}
|
||||||
|
});
|
||||||
Loading…
x
Reference in New Issue
Block a user