Pārlūkot izejas kodu

feat: 首页菜单完成

xyh 2 gadi atpakaļ
vecāks
revīzija
2f2baec35b

+ 5 - 0
src/main.ts

@@ -9,6 +9,7 @@ import {router} from '@routes';
 import {VueQueryPlugin, QueryClient} from '@tanstack/vue-query';
 import {createPinia} from 'pinia';
 import i18n from '@locales';
+import {HomeTwo} from '@icon-park/vue-next';
 
 const client = new QueryClient({
   defaultOptions: {
@@ -27,4 +28,8 @@ app
   .use(createPinia())
   .use(VueQueryPlugin, {queryClient: client});
 
+// #region 注册菜单使用的icon
+app.component('HomeMenuIcon', HomeTwo);
+// #endregion
+
 app.mount('#app');

+ 4 - 0
src/pages/home/index.css

@@ -31,3 +31,7 @@ header {
     height: calc(var(--logo-font-size) + 6px);
   }
 }
+
+.content {
+  overflow: hidden;
+}

+ 5 - 0
src/pages/home/index.vue

@@ -4,6 +4,7 @@ import MenuBtnGroup from './menu-btn-group/index.vue';
 import User from './user/index.vue';
 import {ElHeader, ElContainer} from 'element-plus';
 import Local from './local/index.vue';
+import Menu from './menu/index.vue';
 
 defineOptions({
   name: 'Home',
@@ -21,6 +22,10 @@ defineOptions({
       <User />
       <Local />
     </ElHeader>
+
+    <ElContainer class="content">
+      <Menu />
+    </ElContainer>
   </ElContainer>
 </template>
 

+ 69 - 0
src/pages/home/menu/index.css

@@ -0,0 +1,69 @@
+.aside {
+  display: flex;
+  flex-direction: column;
+  align-items: flex-start;
+  width: 214px;
+  height: 100%;
+  overflow: hidden;
+  background-color: var(--layout-background-color);
+  transition: width 300ms linear;
+}
+
+.aside-collapse {
+  width: calc(var(--el-menu-icon-width) + var(--el-menu-base-level-padding) * 2);
+}
+
+.menu {
+  flex: 1;
+  width: 100% !important;
+  overflow: auto;
+  /* stylelint-disable-next-line declaration-block-no-duplicate-properties */
+  overflow: overlay;
+  border-right: none;
+  transition: width 300ms linear;
+
+  &::-webkit-scrollbar {
+    display: none;
+    width: 6px;
+    background-color: transparent;
+    border-radius: 6px;
+    transition: all 500ms linear;
+  }
+
+  &:hover::-webkit-scrollbar {
+    display: block;
+  }
+
+  &::-webkit-scrollbar-thumb {
+    cursor: pointer;
+    background-color: #ccc;
+    border-radius: 6px;
+
+    &:hover {
+      background-color: var(--primary-color);
+    }
+  }
+}
+
+.collapse-icon {
+  display: flex;
+  justify-content: center;
+  width: 100%;
+  padding: 10px calc(var(--el-menu-base-level-padding) + 2px);
+  font-size: var(--subtitle-font-size);
+  color: var(--font-color);
+  text-align: left;
+  cursor: pointer;
+  border-top: 1px solid #eee;
+
+  &:deep(.i-icon) {
+    transition: transform 300ms linear;
+    transform: rotate(0);
+  }
+}
+
+.collapse-icon-active {
+  &:deep(.i-icon) {
+    transform: rotate(180deg);
+  }
+}

+ 88 - 0
src/pages/home/menu/index.vue

@@ -0,0 +1,88 @@
+<script setup lang='ts'>
+import {ElAside, ElMenu, ElMenuItem, ElSubMenu, ElIcon} from 'element-plus';
+import {MenuFold} from '@icon-park/vue-next';
+import {useToggle} from '@vueuse/core';
+
+defineOptions({name: 'HomeMenu'});
+
+const [collapse, setCollapse] = useToggle();
+
+</script>
+
+<template>
+  <ElAside :class="['aside', {'aside-collapse': collapse}]">
+    <ElMenu
+      class="menu"
+      :collapse="collapse"
+      uniqueOpened
+      menuTrigger="click"
+    >
+      <ElMenuItem index="-1" data-key="-1">
+        <ElIcon>
+          <!--  eslint-disable-next-line vue/require-component-is -->
+          <Component is="HomeMenuIcon" theme="filled" />
+        </ElIcon>
+        <template #title>
+          <span>首页信息首页信息首页信息首页信息首页信息</span>
+        </template>
+      </ElMenuItem>
+      <ElSubMenu index="1">
+        <template #title>
+          <ElIcon>
+            <!--  eslint-disable-next-line vue/require-component-is -->
+            <Component is="HomeMenuIcon" theme="filled" />
+          </ElIcon>
+          <span>基础资料</span>
+        </template>
+        <ElMenuItem index="2">
+          <template #title>
+            <span>首页</span>
+          </template>
+        </ElMenuItem>
+        <ElMenuItem index="3">
+          <template #title>
+            <span>首页</span>
+          </template>
+        </ElMenuItem>
+      </ElSubMenu>
+      <ElSubMenu index="10">
+        <template #title>
+          <ElIcon>
+            <!--  eslint-disable-next-line vue/require-component-is -->
+            <Component is="HomeMenuIcon" theme="filled" />
+          </ElIcon>
+          <span>基础资料</span>
+        </template>
+        <ElMenuItem index="20">
+          <ElIcon>
+            <!--  eslint-disable-next-line vue/require-component-is -->
+            <Component is="HomeMenuIcon" theme="filled" />
+          </ElIcon>
+          <template #title>
+            <span>首页</span>
+          </template>
+        </ElMenuItem>
+        <ElMenuItem index="30">
+          <ElIcon>
+            <!--  eslint-disable-next-line vue/require-component-is -->
+            <Component is="HomeMenuIcon" theme="filled" />
+          </ElIcon>
+          <template #title>
+            <span>首页</span>
+          </template>
+        </ElMenuItem>
+      </ElSubMenu>
+    </ElMenu>
+
+    <div
+      @click="setCollapse(!collapse)"
+      :class="['collapse-icon', {'collapse-icon-active': collapse}]"
+    >
+      <MenuFold theme="filled" />
+    </div>
+  </ElAside>
+</template>
+
+<style scoped>
+@import './index.css';
+</style>

+ 40 - 0
src/styles/elementPlus.css

@@ -8,9 +8,49 @@
   --el-color-primary-light-9: #e7e9f4 !important;
   --el-color-primary-dark-2: #0f2572 !important;
   --el-tag-bg-color: var(--primary-color) !important;
+  --el-menu-text-color: var(--subtitle-font-color) !important;
+  --el-menu-bg-color: var(--layout-background-color) !important;
+  --el-menu-icon-color: var(--tip-font-color);
+  --el-menu-level-padding: 29px !important;
+}
+
+.el-scrollbar__thumb:hover {
+  --el-scrollbar-hover-bg-color: var(--primary-color) !important;
 }
 
 .el-header {
   --el-header-padding: 0 40px !important;
   --el-header-height: 86px !important;
 }
+
+.el-menu-item.is-active {
+  --el-menu-icon-color: var(--primary-color);
+
+  background-color: var(--el-color-primary-light-9) !important;
+  border-inline-end: 4px solid var(--primary-color);
+}
+
+.el-sub-menu:has(.is-active) > .el-sub-menu__title {
+  --el-menu-text-color: var(--primary-color);
+  --el-menu-icon-color: var(--primary-color);
+}
+
+.el-sub-menu .el-menu {
+  background-color: #f9f9f9;
+}
+
+.el-menu-item {
+  & span {
+    flex: 1;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+  }
+}
+
+.el-sub-menu__title,
+.el-menu-item {
+  & .i-icon {
+    color: var(--el-menu-icon-color);
+  }
+}

+ 1 - 0
src/styles/variable.css

@@ -15,4 +15,5 @@
   --title-font-color: #000;
   --subtitle-font-color: #333;
   --font-color: #666;
+  --tip-font-color: #999;
 }