Skip to content

Commit 2ebb584

Browse files
committed
feat: 在左侧菜单右中侧再加一个折叠展开菜单的功能
1 parent 791224b commit 2ebb584

File tree

5 files changed

+85
-6
lines changed

5 files changed

+85
-6
lines changed

build/info.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import boxen, { type Options as BoxenOptions } from "boxen";
77
dayjs.extend(duration);
88

99
const welcomeMessage = gradientString("cyan", "magenta").multiline(
10-
`Hello! 欢迎使用 pure-admin 开源项目\n我们为您精心准备了下面两个贴心的保姆级文档\nhttps://yiming_chang.gitee.io/pure-admin-doc\nhttps://pure-admin-utils.netlify.app`
10+
`您好! 欢迎使用 pure-admin 开源项目\n我们为您精心准备了下面两个贴心的保姆级文档\nhttps://yiming_chang.gitee.io/pure-admin-doc\nhttps://pure-admin-utils.netlify.app`
1111
);
1212

1313
const boxenOptions: BoxenOptions = {
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
<script setup lang="ts">
2+
import { computed } from "vue";
3+
import { useGlobal } from "@pureadmin/utils";
4+
import { useNav } from "@/layout/hooks/useNav";
5+
6+
import ArrowLeft from "@iconify-icons/ri/arrow-left-double-fill";
7+
8+
interface Props {
9+
isActive: boolean;
10+
}
11+
12+
const props = withDefaults(defineProps<Props>(), {
13+
isActive: false
14+
});
15+
16+
const { tooltipEffect } = useNav();
17+
18+
const iconClass = computed(() => {
19+
return ["w-[16px]", "h-[16px]"];
20+
});
21+
22+
const { $storage } = useGlobal<GlobalPropertiesApi>();
23+
const themeColor = computed(() => $storage.layout?.themeColor);
24+
25+
const emit = defineEmits<{
26+
(e: "toggleClick"): void;
27+
}>();
28+
29+
const toggleClick = () => {
30+
emit("toggleClick");
31+
};
32+
</script>
33+
34+
<template>
35+
<div
36+
v-tippy="{
37+
content: props.isActive ? '点击折叠' : '点击展开',
38+
theme: tooltipEffect,
39+
hideOnClick: 'toggle',
40+
placement: 'right'
41+
}"
42+
class="center-collapse"
43+
@click="toggleClick"
44+
>
45+
<IconifyIconOffline
46+
:icon="ArrowLeft"
47+
:class="[iconClass, themeColor === 'light' ? '' : 'text-primary']"
48+
:style="{ transform: props.isActive ? 'none' : 'rotateY(180deg)' }"
49+
/>
50+
</div>
51+
</template>
52+
53+
<style lang="scss" scoped>
54+
.center-collapse {
55+
position: absolute;
56+
top: 50%;
57+
right: 2px;
58+
z-index: 1002;
59+
display: flex;
60+
align-items: center;
61+
justify-content: center;
62+
width: 24px;
63+
height: 34px;
64+
cursor: pointer;
65+
background: var(--el-bg-color);
66+
border: 1px solid var(--pure-border-color);
67+
border-radius: 4px;
68+
transform: translate(12px, -50%);
69+
}
70+
</style>

src/layout/components/sidebar/leftCollapse.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ const toggleClick = () => {
4141
</script>
4242

4343
<template>
44-
<div class="collapse-container">
44+
<div class="left-collapse">
4545
<IconifyIconOffline
4646
v-tippy="{
4747
content: props.isActive ? '点击折叠' : '点击展开',
@@ -58,7 +58,7 @@ const toggleClick = () => {
5858
</template>
5959

6060
<style lang="scss" scoped>
61-
.collapse-container {
61+
.left-collapse {
6262
position: absolute;
6363
bottom: 0;
6464
width: 100%;

src/layout/components/sidebar/vertical.vue

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ import Logo from "./logo.vue";
33
import { useRoute } from "vue-router";
44
import { emitter } from "@/utils/mitt";
55
import SidebarItem from "./sidebarItem.vue";
6-
import leftCollapse from "./leftCollapse.vue";
6+
import LeftCollapse from "./leftCollapse.vue";
77
import { useNav } from "@/layout/hooks/useNav";
8+
import CenterCollapse from "./centerCollapse.vue";
89
import { responsiveStorageNameSpace } from "@/config";
910
import { storageLocal, isAllEmpty } from "@pureadmin/utils";
1011
import { findRouteByPath, getParentPaths } from "@/router/utils";
1112
import { usePermissionStoreHook } from "@/store/modules/permission";
1213
import { ref, computed, watch, onMounted, onBeforeUnmount } from "vue";
1314
1415
const route = useRoute();
16+
const isShow = ref(false);
1517
const showLogo = ref(
1618
storageLocal().getItem<StorageConfigs>(
1719
`${responsiveStorageNameSpace()}configure`
@@ -88,6 +90,8 @@ onBeforeUnmount(() => {
8890
<div
8991
v-loading="loading"
9092
:class="['sidebar-container', showLogo ? 'has-logo' : 'no-logo']"
93+
@mouseenter.prevent="isShow = true"
94+
@mouseleave.prevent="isShow = false"
9195
>
9296
<Logo v-if="showLogo" :collapse="isCollapse" />
9397
<el-scrollbar
@@ -114,7 +118,12 @@ onBeforeUnmount(() => {
114118
/>
115119
</el-menu>
116120
</el-scrollbar>
117-
<leftCollapse
121+
<CenterCollapse
122+
v-if="device !== 'mobile' && (isShow || isCollapse)"
123+
:is-active="pureApp.sidebar.opened"
124+
@toggleClick="toggleSideBar"
125+
/>
126+
<LeftCollapse
118127
v-if="device !== 'mobile'"
119128
:is-active="pureApp.sidebar.opened"
120129
@toggleClick="toggleSideBar"

src/style/sidebar.scss

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
z-index: 1001;
9393
width: $sideBarWidth !important;
9494
height: 100%;
95-
overflow: hidden;
95+
overflow: visible;
9696
font-size: 0;
9797
background: $menuBg;
9898
border-right: 1px solid var(--pure-border-color);

0 commit comments

Comments
 (0)