|
@@ -3,10 +3,12 @@ import path from "path";
|
|
|
import { getConfig } from "@/config";
|
|
|
import { menuType } from "../../types";
|
|
|
import extraIcon from "./extraIcon.vue";
|
|
|
+import { useDark } from "@pureadmin/utils";
|
|
|
+import { ReText } from "@/components/ReText";
|
|
|
import { useNav } from "@/layout/hooks/useNav";
|
|
|
import { transformI18n } from "@/plugins/i18n";
|
|
|
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
|
|
|
-import { ref, toRaw, PropType, nextTick, computed, CSSProperties } from "vue";
|
|
|
+import { type CSSProperties, type PropType, computed, ref, toRaw } from "vue";
|
|
|
|
|
|
import ArrowUp from "@iconify-icons/ep/arrow-up-bold";
|
|
|
import EpArrowDown from "@iconify-icons/ep/arrow-down-bold";
|
|
@@ -14,6 +16,7 @@ import ArrowLeft from "@iconify-icons/ep/arrow-left-bold";
|
|
|
import ArrowRight from "@iconify-icons/ep/arrow-right-bold";
|
|
|
|
|
|
const { layout, isCollapse, tooltipEffect, getDivStyle } = useNav();
|
|
|
+const { isDark } = useDark();
|
|
|
|
|
|
const props = defineProps({
|
|
|
item: {
|
|
@@ -29,13 +32,6 @@ const props = defineProps({
|
|
|
}
|
|
|
});
|
|
|
|
|
|
-const getSpanStyle = computed((): CSSProperties => {
|
|
|
- return {
|
|
|
- width: "100%",
|
|
|
- textAlign: "center"
|
|
|
- };
|
|
|
-});
|
|
|
-
|
|
|
const getNoDropdownStyle = computed((): CSSProperties => {
|
|
|
return {
|
|
|
display: "flex",
|
|
@@ -43,15 +39,7 @@ const getNoDropdownStyle = computed((): CSSProperties => {
|
|
|
};
|
|
|
});
|
|
|
|
|
|
-const getMenuTextStyle = computed(() => {
|
|
|
- return {
|
|
|
- overflow: "hidden",
|
|
|
- textOverflow: "ellipsis",
|
|
|
- outline: "none"
|
|
|
- };
|
|
|
-});
|
|
|
-
|
|
|
-const getsubMenuIconStyle = computed((): CSSProperties => {
|
|
|
+const getSubMenuIconStyle = computed((): CSSProperties => {
|
|
|
return {
|
|
|
display: "flex",
|
|
|
justifyContent: "center",
|
|
@@ -65,43 +53,6 @@ const getsubMenuIconStyle = computed((): CSSProperties => {
|
|
|
};
|
|
|
});
|
|
|
|
|
|
-const getSubTextStyle = computed((): CSSProperties => {
|
|
|
- if (!isCollapse.value) {
|
|
|
- return {
|
|
|
- width: "210px",
|
|
|
- display: "inline-block",
|
|
|
- overflow: "hidden",
|
|
|
- textOverflow: "ellipsis"
|
|
|
- };
|
|
|
- } else {
|
|
|
- return {
|
|
|
- width: ""
|
|
|
- };
|
|
|
- }
|
|
|
-});
|
|
|
-
|
|
|
-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 {
|
|
@@ -113,41 +64,6 @@ const expandCloseIcon = computed(() => {
|
|
|
});
|
|
|
|
|
|
const onlyOneChild: menuType = ref(null);
|
|
|
-// 存放菜单是否存在showTooltip属性标识
|
|
|
-const hoverMenuMap = new WeakMap();
|
|
|
-// 存储菜单文本dom元素
|
|
|
-const menuTextRef = ref(null);
|
|
|
-
|
|
|
-function hoverMenu(key) {
|
|
|
- // 如果当前菜单showTooltip属性已存在,退出计算
|
|
|
- if (hoverMenuMap.get(key)) return;
|
|
|
-
|
|
|
- nextTick(() => {
|
|
|
- // 如果文本内容的整体宽度大于其可视宽度,则文本溢出
|
|
|
- menuTextRef.value?.scrollWidth > menuTextRef.value?.clientWidth
|
|
|
- ? Object.assign(key, {
|
|
|
- showTooltip: true
|
|
|
- })
|
|
|
- : Object.assign(key, {
|
|
|
- showTooltip: false
|
|
|
- });
|
|
|
- hoverMenuMap.set(key, true);
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-// 左侧菜单折叠后,当菜单没有图标时只显示第一个文字并加上省略号
|
|
|
-function overflowSlice(text, item?: any) {
|
|
|
- const newText =
|
|
|
- (text?.length > 1 ? text.toString().slice(0, 1) : text) + "...";
|
|
|
- if (item && !(isCollapse.value && item?.parentId === null)) {
|
|
|
- return layout.value === "mix" &&
|
|
|
- item?.pathList?.length === 2 &&
|
|
|
- isCollapse.value
|
|
|
- ? newText
|
|
|
- : text;
|
|
|
- }
|
|
|
- return newText;
|
|
|
-}
|
|
|
|
|
|
function hasOneShowingChild(children: menuType[] = [], parent: menuType) {
|
|
|
const showingChildren = children.filter((item: any) => {
|
|
@@ -194,7 +110,7 @@ function resolvePath(routePath) {
|
|
|
<div
|
|
|
v-if="toRaw(props.item.meta.icon)"
|
|
|
class="sub-menu-icon"
|
|
|
- :style="getsubMenuIconStyle"
|
|
|
+ :style="getSubMenuIconStyle"
|
|
|
>
|
|
|
<component
|
|
|
:is="
|
|
@@ -205,51 +121,34 @@ function resolvePath(routePath) {
|
|
|
"
|
|
|
/>
|
|
|
</div>
|
|
|
- <span
|
|
|
+ <el-text
|
|
|
v-if="
|
|
|
- !props.item?.meta.icon &&
|
|
|
- isCollapse &&
|
|
|
- layout === 'vertical' &&
|
|
|
- props.item?.pathList?.length === 1
|
|
|
+ (!props.item?.meta.icon &&
|
|
|
+ isCollapse &&
|
|
|
+ layout === 'vertical' &&
|
|
|
+ props.item?.pathList?.length === 1) ||
|
|
|
+ (!onlyOneChild.meta.icon &&
|
|
|
+ isCollapse &&
|
|
|
+ layout === 'mix' &&
|
|
|
+ props.item?.pathList?.length === 2)
|
|
|
"
|
|
|
- :style="getSpanStyle"
|
|
|
+ truncated
|
|
|
+ class="!px-4 !text-inherit"
|
|
|
>
|
|
|
- {{ overflowSlice(transformI18n(onlyOneChild.meta.title)) }}
|
|
|
- </span>
|
|
|
- <span
|
|
|
- v-if="
|
|
|
- !onlyOneChild.meta.icon &&
|
|
|
- isCollapse &&
|
|
|
- layout === 'mix' &&
|
|
|
- props.item?.pathList?.length === 2
|
|
|
- "
|
|
|
- :style="getSpanStyle"
|
|
|
- >
|
|
|
- {{ overflowSlice(transformI18n(onlyOneChild.meta.title)) }}
|
|
|
- </span>
|
|
|
+ {{ transformI18n(onlyOneChild.meta.title) }}
|
|
|
+ </el-text>
|
|
|
+
|
|
|
<template #title>
|
|
|
<div :style="getDivStyle">
|
|
|
- <span v-if="layout === 'horizontal'">
|
|
|
- {{ transformI18n(onlyOneChild.meta.title) }}
|
|
|
- </span>
|
|
|
- <el-tooltip
|
|
|
- v-else
|
|
|
- placement="top"
|
|
|
- :effect="tooltipEffect"
|
|
|
- :offset="-10"
|
|
|
- :disabled="!onlyOneChild.showTooltip"
|
|
|
+ <ReText
|
|
|
+ :tippyProps="{
|
|
|
+ offset: [0, -10],
|
|
|
+ theme: !isDark ? tooltipEffect : undefined
|
|
|
+ }"
|
|
|
+ class="!text-inherit"
|
|
|
>
|
|
|
- <template #content>
|
|
|
- {{ transformI18n(onlyOneChild.meta.title) }}
|
|
|
- </template>
|
|
|
- <span
|
|
|
- ref="menuTextRef"
|
|
|
- :style="getMenuTextStyle"
|
|
|
- @mouseover="hoverMenu(onlyOneChild)"
|
|
|
- >
|
|
|
- {{ transformI18n(onlyOneChild.meta.title) }}
|
|
|
- </span>
|
|
|
- </el-tooltip>
|
|
|
+ {{ transformI18n(onlyOneChild.meta.title) }}
|
|
|
+ </ReText>
|
|
|
<extraIcon :extraIcon="onlyOneChild.meta.extraIcon" />
|
|
|
</div>
|
|
|
</template>
|
|
@@ -264,48 +163,38 @@ function resolvePath(routePath) {
|
|
|
<template #title>
|
|
|
<div
|
|
|
v-if="toRaw(props.item.meta.icon)"
|
|
|
- :style="getsubMenuIconStyle"
|
|
|
+ :style="getSubMenuIconStyle"
|
|
|
class="sub-menu-icon"
|
|
|
>
|
|
|
<component
|
|
|
:is="useRenderIcon(props.item.meta && toRaw(props.item.meta.icon))"
|
|
|
/>
|
|
|
</div>
|
|
|
- <span v-if="layout === 'horizontal'">
|
|
|
- {{ transformI18n(props.item.meta.title) }}
|
|
|
- </span>
|
|
|
- <div
|
|
|
+ <ReText
|
|
|
v-if="
|
|
|
!(
|
|
|
+ layout === 'vertical' &&
|
|
|
isCollapse &&
|
|
|
toRaw(props.item.meta.icon) &&
|
|
|
props.item.parentId === null
|
|
|
)
|
|
|
"
|
|
|
- :style="getSubMenuDivStyle(props.item)"
|
|
|
+ :tippyProps="{
|
|
|
+ offset: [0, -10],
|
|
|
+ theme: !isDark ? tooltipEffect : undefined
|
|
|
+ }"
|
|
|
+ :class="{
|
|
|
+ '!text-inherit': true,
|
|
|
+ '!px-4':
|
|
|
+ layout !== 'horizontal' &&
|
|
|
+ isCollapse &&
|
|
|
+ !toRaw(props.item.meta.icon) &&
|
|
|
+ props.item.parentId === null
|
|
|
+ }"
|
|
|
>
|
|
|
- <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>
|
|
|
+ {{ transformI18n(props.item.meta.title) }}
|
|
|
+ </ReText>
|
|
|
+ <extraIcon v-if="!isCollapse" :extraIcon="props.item.meta.extraIcon" />
|
|
|
</template>
|
|
|
|
|
|
<sidebar-item
|