瀏覽代碼

feat: 优化菜单名称右侧的额外图标,使其支持更多图标渲染模式

xiaoxian521 2 年之前
父節點
當前提交
b455b2da89

+ 20 - 0
src/layout/components/sidebar/extraIcon.vue

@@ -0,0 +1,20 @@
+<script setup lang="ts">
+import { toRaw } from "vue";
+import { useRenderIcon } from "@/components/ReIcon/src/hooks";
+
+const props = defineProps({
+  extraIcon: {
+    type: String,
+    default: ""
+  }
+});
+</script>
+
+<template>
+  <div v-if="props.extraIcon" class="flex justify-center items-center">
+    <component
+      :is="useRenderIcon(toRaw(props.extraIcon))"
+      class="w-[30px] h-[30px]"
+    />
+  </div>
+</template>

+ 8 - 9
src/layout/components/sidebar/mixNav.vue

@@ -1,4 +1,5 @@
 <script setup lang="ts">
+import extraIcon from "./extraIcon.vue";
 import Search from "../search/index.vue";
 import Notice from "../notice/index.vue";
 import { useNav } from "@/layout/hooks/useNav";
@@ -26,6 +27,7 @@ const {
   menuSelect,
   resolvePath,
   username,
+  getDivStyle,
   avatarsStyle,
   getDropdownItemStyle,
   getDropdownItemClass
@@ -85,15 +87,12 @@ watch(
               :is="useRenderIcon(route.meta && toRaw(route.meta.icon))"
             />
           </div>
-          <span class="select-none">{{ transformI18n(route.meta.title) }}</span>
-          <FontIcon
-            v-if="route.meta.extraIcon"
-            width="30px"
-            height="30px"
-            style="position: absolute; right: 10px"
-            :icon="route.meta.extraIcon.name"
-            :svg="route.meta.extraIcon.svg ? true : false"
-          />
+          <div :style="getDivStyle">
+            <span class="select-none">
+              {{ transformI18n(route.meta.title) }}
+            </span>
+            <extraIcon :extraIcon="route.meta.extraIcon" />
+          </div>
         </template>
       </el-menu-item>
     </el-menu>

+ 50 - 43
src/layout/components/sidebar/sidebarItem.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import path from "path";
 import { getConfig } from "@/config";
+import extraIcon from "./extraIcon.vue";
 import { childrenType } from "../../types";
 import { useNav } from "@/layout/hooks/useNav";
 import { transformI18n } from "@/plugins/i18n";
@@ -12,7 +13,7 @@ import EpArrowDown from "@iconify-icons/ep/arrow-down";
 import ArrowLeft from "@iconify-icons/ep/arrow-left";
 import ArrowRight from "@iconify-icons/ep/arrow-right";
 
-const { layout, isCollapse, tooltipEffect } = useNav();
+const { layout, isCollapse, tooltipEffect, getDivStyle } = useNav();
 
 const props = defineProps({
   item: {
@@ -50,16 +51,6 @@ const getMenuTextStyle = computed(() => {
   };
 });
 
-const getDivStyle = computed((): CSSProperties => {
-  return {
-    width: "100%",
-    display: "flex",
-    alignItems: "center",
-    justifyContent: "space-between",
-    overflow: "hidden"
-  };
-});
-
 const getsubMenuIconStyle = computed((): CSSProperties => {
   return {
     display: "flex",
@@ -89,6 +80,28 @@ const getSubTextStyle = computed((): CSSProperties => {
   }
 });
 
+const getSubMenuDivStyle = computed((): any => {
+  return item => {
+    return !isCollapse.value
+      ? {
+          width: "100%",
+          display: "flex",
+          alignItems: "center",
+          justifyContent: "space-between",
+          overflow: "hidden"
+        }
+      : {
+          width: "100%",
+          textAlign:
+            item?.parentId === null
+              ? "center"
+              : layout.value === "mix" && item?.pathList?.length === 2
+              ? "center"
+              : ""
+        };
+  };
+});
+
 const expandCloseIcon = computed(() => {
   if (!getConfig()?.MenuArrowIconNoTransition) return "";
   return {
@@ -240,13 +253,7 @@ function resolvePath(routePath) {
             {{ transformI18n(onlyOneChild.meta.title) }}
           </span>
         </el-tooltip>
-        <FontIcon
-          v-if="onlyOneChild.meta.extraIcon"
-          width="30px"
-          height="30px"
-          :icon="onlyOneChild.meta.extraIcon.name"
-          :svg="onlyOneChild.meta.extraIcon.svg ? true : false"
-        />
+        <extraIcon :extraIcon="onlyOneChild.meta.extraIcon" />
       </div>
     </template>
   </el-menu-item>
@@ -267,41 +274,41 @@ function resolvePath(routePath) {
           :is="useRenderIcon(props.item.meta && toRaw(props.item.meta.icon))"
         />
       </div>
-      <span v-if="layout === 'horizontal'">
-        {{ transformI18n(props.item.meta.title) }}
-      </span>
-      <el-tooltip
+      <div
+        :style="getSubMenuDivStyle(props.item)"
         v-if="
-          layout !== 'horizontal' &&
           !(
             isCollapse &&
             toRaw(props.item.meta.icon) &&
             props.item.parentId === null
           )
         "
-        placement="top"
-        :effect="tooltipEffect"
-        :offset="-10"
-        :disabled="!props.item.showTooltip"
       >
-        <template #content>
+        <span v-if="layout === 'horizontal'">
           {{ transformI18n(props.item.meta.title) }}
-        </template>
-        <span
-          ref="menuTextRef"
-          :style="getSubTextStyle"
-          @mouseover="hoverMenu(props.item)"
-        >
-          {{ overflowSlice(transformI18n(props.item.meta.title), props.item) }}
         </span>
-      </el-tooltip>
-      <FontIcon
-        v-if="props.item.meta.extraIcon"
-        width="30px"
-        height="30px"
-        :icon="props.item.meta.extraIcon.name"
-        :svg="props.item.meta.extraIcon.svg ? true : false"
-      />
+        <el-tooltip
+          v-if="layout !== 'horizontal'"
+          placement="top"
+          :effect="tooltipEffect"
+          :offset="-10"
+          :disabled="!props.item.showTooltip"
+        >
+          <template #content>
+            {{ transformI18n(props.item.meta.title) }}
+          </template>
+          <span
+            ref="menuTextRef"
+            :style="getSubTextStyle"
+            @mouseover="hoverMenu(props.item)"
+          >
+            {{
+              overflowSlice(transformI18n(props.item.meta.title), props.item)
+            }}
+          </span>
+        </el-tooltip>
+        <extraIcon v-if="!isCollapse" :extraIcon="props.item.meta.extraIcon" />
+      </div>
     </template>
     <sidebar-item
       v-for="child in props.item.children"

+ 12 - 1
src/layout/hooks/useNav.ts

@@ -1,4 +1,3 @@
-import { computed } from "vue";
 import { storeToRefs } from "pinia";
 import { getConfig } from "@/config";
 import { useRouter } from "vue-router";
@@ -7,6 +6,7 @@ import { routeMetaType } from "../types";
 import { useGlobal } from "@pureadmin/utils";
 import { transformI18n } from "@/plugins/i18n";
 import { router, remainingPaths } from "@/router";
+import { computed, type CSSProperties } from "vue";
 import { useAppStoreHook } from "@/store/modules/app";
 import { useUserStoreHook } from "@/store/modules/user";
 import { useEpThemeStoreHook } from "@/store/modules/epTheme";
@@ -21,6 +21,16 @@ export function useNav() {
   /** 平台`layout`中所有`el-tooltip`的`effect`配置,默认`light` */
   const tooltipEffect = getConfig()?.TooltipEffect ?? "light";
 
+  const getDivStyle = computed((): CSSProperties => {
+    return {
+      width: "100%",
+      display: "flex",
+      alignItems: "center",
+      justifyContent: "space-between",
+      overflow: "hidden"
+    };
+  });
+
   /** 用户名 */
   const username = computed(() => {
     return useUserStoreHook()?.username;
@@ -146,6 +156,7 @@ export function useNav() {
     $storage,
     backHome,
     onPanel,
+    getDivStyle,
     changeTitle,
     toggleSideBar,
     menuSelect,

+ 1 - 4
src/layout/types.ts

@@ -67,10 +67,7 @@ export type childrenType = {
     icon?: string;
     title?: string;
     showParent?: boolean;
-    extraIcon?: {
-      svg?: boolean;
-      name?: string;
-    };
+    extraIcon?: string;
   };
   showTooltip?: boolean;
   parentId?: number;

+ 1 - 4
src/router/modules/components.ts

@@ -16,10 +16,7 @@ export default {
       component: () => import("@/views/components/message/index.vue"),
       meta: {
         title: $t("menus.hsmessage"),
-        extraIcon: {
-          svg: true,
-          name: "pure-iconfont-new"
-        },
+        extraIcon: "IF-pure-iconfont-new svg",
         transition: {
           enterTransition: "animate__fadeInLeft",
           leaveTransition: "animate__fadeOutRight"

+ 1 - 4
src/router/modules/nested.ts

@@ -53,10 +53,7 @@ export default {
               meta: {
                 title: $t("menus.hsmenu1-2-2"),
                 keepAlive: true,
-                extraIcon: {
-                  svg: true,
-                  name: "pure-iconfont-new"
-                }
+                extraIcon: "IF-pure-iconfont-new svg"
               }
             }
           ]

+ 2 - 5
types/global.d.ts

@@ -192,11 +192,8 @@ declare global {
       title: string;
       /** 菜单图标 `可选` */
       icon?: string | FunctionalComponent | IconifyIcon;
-      /** 菜单名称右侧的额外图标,支持`fontawesome`、`iconfont`、`element-plus-icon` `可选` */
-      extraIcon?: {
-        svg?: boolean;
-        name?: string;
-      };
+      /** 菜单名称右侧的额外图标 */
+      extraIcon?: string | FunctionalComponent | IconifyIcon;
       /** 是否在菜单中显示(默认`true`)`可选` */
       showLink?: boolean;
       /** 是否显示父级菜单 `可选` */