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

This commit is contained in:
xiaoxian521 2023-02-09 20:04:57 +08:00
parent e323411d1c
commit b455b2da89
8 changed files with 95 additions and 70 deletions

View File

@ -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>

View File

@ -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>

View File

@ -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"

View File

@ -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,

View File

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

View File

@ -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"

View File

@ -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"
}
}
]

7
types/global.d.ts vendored
View File

@ -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;
/** 是否显示父级菜单 `可选` */