mirror of
https://github.com/pure-admin/pure-admin-thin.git
synced 2025-11-17 08:03:37 +08:00
release: update 5.1.0
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
import { isEqual } from "@pureadmin/utils";
|
||||
import { transformI18n } from "@/plugins/i18n";
|
||||
import { useRoute, useRouter } from "vue-router";
|
||||
import { ref, watch, onMounted, toRaw } from "vue";
|
||||
import { getParentPaths, findRouteByPath } from "@/router/utils";
|
||||
import { useMultiTagsStoreHook } from "@/store/modules/multiTags";
|
||||
import { useRoute, useRouter, RouteLocationMatched } from "vue-router";
|
||||
|
||||
const route = useRoute();
|
||||
const levelList = ref([]);
|
||||
@@ -64,12 +64,28 @@ const getBreadcrumb = (): void => {
|
||||
);
|
||||
};
|
||||
|
||||
const handleLink = (item: RouteLocationMatched): void => {
|
||||
const { redirect, path } = item;
|
||||
const handleLink = item => {
|
||||
const { redirect, name, path } = item;
|
||||
if (redirect) {
|
||||
router.push(redirect as any);
|
||||
} else {
|
||||
router.push(path);
|
||||
if (name) {
|
||||
if (item.query) {
|
||||
router.push({
|
||||
name,
|
||||
query: item.query
|
||||
});
|
||||
} else if (item.params) {
|
||||
router.push({
|
||||
name,
|
||||
params: item.params
|
||||
});
|
||||
} else {
|
||||
router.push({ name });
|
||||
}
|
||||
} else {
|
||||
router.push({ path });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -92,9 +108,9 @@ watch(
|
||||
<el-breadcrumb class="!leading-[50px] select-none" separator="/">
|
||||
<transition-group name="breadcrumb">
|
||||
<el-breadcrumb-item
|
||||
class="!inline !items-stretch"
|
||||
v-for="item in levelList"
|
||||
:key="item.path"
|
||||
class="!inline !items-stretch"
|
||||
>
|
||||
<a @click.prevent="handleLink(item)">
|
||||
{{ transformI18n(item.meta.title) }}
|
||||
|
||||
@@ -21,6 +21,7 @@ const {
|
||||
logout,
|
||||
backTopMenu,
|
||||
onPanel,
|
||||
getLogo,
|
||||
username,
|
||||
userAvatar,
|
||||
avatarsStyle,
|
||||
@@ -43,13 +44,14 @@ nextTick(() => {
|
||||
class="horizontal-header"
|
||||
>
|
||||
<div class="horizontal-header-left" @click="backTopMenu">
|
||||
<img src="/logo.svg" alt="logo" />
|
||||
<img :src="getLogo()" alt="logo" />
|
||||
<span>{{ title }}</span>
|
||||
</div>
|
||||
<el-menu
|
||||
router
|
||||
ref="menuRef"
|
||||
router
|
||||
mode="horizontal"
|
||||
popper-class="pure-scrollbar"
|
||||
class="horizontal-header-menu"
|
||||
:default-active="defaultActive"
|
||||
>
|
||||
@@ -62,7 +64,7 @@ nextTick(() => {
|
||||
</el-menu>
|
||||
<div class="horizontal-header-right">
|
||||
<!-- 菜单搜索 -->
|
||||
<Search />
|
||||
<Search id="header-search" />
|
||||
<!-- 通知 -->
|
||||
<Notice id="header-notice" />
|
||||
<!-- 国际化 -->
|
||||
@@ -77,7 +79,7 @@ nextTick(() => {
|
||||
:class="['dark:!text-white', getDropdownItemClass(locale, 'zh')]"
|
||||
@click="translationCh"
|
||||
>
|
||||
<span class="check-zh" v-show="locale === 'zh'">
|
||||
<span v-show="locale === 'zh'" class="check-zh">
|
||||
<IconifyIconOffline :icon="Check" />
|
||||
</span>
|
||||
简体中文
|
||||
@@ -87,7 +89,7 @@ nextTick(() => {
|
||||
:class="['dark:!text-white', getDropdownItemClass(locale, 'en')]"
|
||||
@click="translationEn"
|
||||
>
|
||||
<span class="check-en" v-show="locale === 'en'">
|
||||
<span v-show="locale === 'en'" class="check-en">
|
||||
<IconifyIconOffline :icon="Check" />
|
||||
</span>
|
||||
English
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, computed } from "vue";
|
||||
import { computed } from "vue";
|
||||
import { useGlobal } from "@pureadmin/utils";
|
||||
import { useNav } from "@/layout/hooks/useNav";
|
||||
|
||||
import MenuFold from "@iconify-icons/ri/menu-fold-fill";
|
||||
|
||||
interface Props {
|
||||
@@ -11,7 +13,6 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
isActive: false
|
||||
});
|
||||
|
||||
const visible = ref(false);
|
||||
const { tooltipEffect } = useNav();
|
||||
|
||||
const iconClass = computed(() => {
|
||||
@@ -22,14 +23,14 @@ const iconClass = computed(() => {
|
||||
"h-[16px]",
|
||||
"inline-block",
|
||||
"align-middle",
|
||||
"text-primary",
|
||||
"cursor-pointer",
|
||||
"duration-[100ms]",
|
||||
"hover:text-primary",
|
||||
"dark:hover:!text-white"
|
||||
"duration-[100ms]"
|
||||
];
|
||||
});
|
||||
|
||||
const { $storage } = useGlobal<GlobalPropertiesApi>();
|
||||
const themeColor = computed(() => $storage.layout?.themeColor);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "toggleClick"): void;
|
||||
}>();
|
||||
@@ -40,32 +41,29 @@ const toggleClick = () => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="container">
|
||||
<el-tooltip
|
||||
placement="right"
|
||||
:visible="visible"
|
||||
:effect="tooltipEffect"
|
||||
:content="props.isActive ? '点击折叠' : '点击展开'"
|
||||
>
|
||||
<IconifyIconOffline
|
||||
:icon="MenuFold"
|
||||
:class="iconClass"
|
||||
:style="{ transform: props.isActive ? 'none' : 'rotateY(180deg)' }"
|
||||
@click="toggleClick"
|
||||
@mouseenter="visible = true"
|
||||
@mouseleave="visible = false"
|
||||
/>
|
||||
</el-tooltip>
|
||||
<div class="collapse-container">
|
||||
<IconifyIconOffline
|
||||
v-tippy="{
|
||||
content: props.isActive ? '点击折叠' : '点击展开',
|
||||
theme: tooltipEffect,
|
||||
hideOnClick: 'toggle',
|
||||
placement: 'right'
|
||||
}"
|
||||
:icon="MenuFold"
|
||||
:class="[iconClass, themeColor === 'light' ? '' : 'text-primary']"
|
||||
:style="{ transform: props.isActive ? 'none' : 'rotateY(180deg)' }"
|
||||
@click="toggleClick"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.container {
|
||||
.collapse-container {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
height: 40px;
|
||||
line-height: 40px;
|
||||
box-shadow: 0 0 6px -2px var(--el-color-primary);
|
||||
box-shadow: 0 0 6px -3px var(--el-color-primary);
|
||||
}
|
||||
</style>
|
||||
|
||||
36
src/layout/components/sidebar/linkItem.vue
Normal file
36
src/layout/components/sidebar/linkItem.vue
Normal file
@@ -0,0 +1,36 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
import { isUrl } from "@pureadmin/utils";
|
||||
import { menuType } from "@/layout/types";
|
||||
|
||||
defineOptions({
|
||||
name: "LinkItem"
|
||||
});
|
||||
|
||||
const props = defineProps<{
|
||||
to: menuType;
|
||||
}>();
|
||||
|
||||
const isExternalLink = computed(() => isUrl(props.to.name));
|
||||
const getLinkProps = (item: menuType) => {
|
||||
if (isExternalLink.value) {
|
||||
return {
|
||||
href: item.name,
|
||||
target: "_blank",
|
||||
rel: "noopener"
|
||||
};
|
||||
}
|
||||
return {
|
||||
to: item
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<component
|
||||
:is="isExternalLink ? 'a' : 'router-link'"
|
||||
v-bind="getLinkProps(to)"
|
||||
>
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
@@ -6,7 +6,7 @@ const props = defineProps({
|
||||
collapse: Boolean
|
||||
});
|
||||
|
||||
const { title } = useNav();
|
||||
const { title, getLogo } = useNav();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -19,7 +19,7 @@ const { title } = useNav();
|
||||
class="sidebar-logo-link"
|
||||
:to="getTopMenu()?.path ?? '/'"
|
||||
>
|
||||
<img src="/logo.svg" alt="logo" />
|
||||
<img :src="getLogo()" alt="logo" />
|
||||
<span class="sidebar-title">{{ title }}</span>
|
||||
</router-link>
|
||||
<router-link
|
||||
@@ -29,7 +29,7 @@ const { title } = useNav();
|
||||
class="sidebar-logo-link"
|
||||
:to="getTopMenu()?.path ?? '/'"
|
||||
>
|
||||
<img src="/logo.svg" alt="logo" />
|
||||
<img :src="getLogo()" alt="logo" />
|
||||
<span class="sidebar-title">{{ title }}</span>
|
||||
</router-link>
|
||||
</transition>
|
||||
@@ -48,6 +48,7 @@ const { title } = useNav();
|
||||
flex-wrap: nowrap;
|
||||
align-items: center;
|
||||
height: 100%;
|
||||
padding-left: 10px;
|
||||
|
||||
img {
|
||||
display: inline-block;
|
||||
|
||||
@@ -61,13 +61,14 @@ watch(
|
||||
<template>
|
||||
<div
|
||||
v-if="device !== 'mobile'"
|
||||
class="horizontal-header"
|
||||
v-loading="usePermissionStoreHook().wholeMenus.length === 0"
|
||||
class="horizontal-header"
|
||||
>
|
||||
<el-menu
|
||||
router
|
||||
ref="menuRef"
|
||||
router
|
||||
mode="horizontal"
|
||||
popper-class="pure-scrollbar"
|
||||
class="horizontal-header-menu"
|
||||
:default-active="defaultActive"
|
||||
>
|
||||
@@ -96,7 +97,7 @@ watch(
|
||||
</el-menu>
|
||||
<div class="horizontal-header-right">
|
||||
<!-- 菜单搜索 -->
|
||||
<Search />
|
||||
<Search id="header-search" />
|
||||
<!-- 通知 -->
|
||||
<Notice id="header-notice" />
|
||||
<!-- 国际化 -->
|
||||
@@ -111,7 +112,7 @@ watch(
|
||||
:class="['dark:!text-white', getDropdownItemClass(locale, 'zh')]"
|
||||
@click="translationCh"
|
||||
>
|
||||
<span class="check-zh" v-show="locale === 'zh'">
|
||||
<span v-show="locale === 'zh'" class="check-zh">
|
||||
<IconifyIconOffline :icon="Check" />
|
||||
</span>
|
||||
简体中文
|
||||
@@ -121,7 +122,7 @@ watch(
|
||||
:class="['dark:!text-white', getDropdownItemClass(locale, 'en')]"
|
||||
@click="translationEn"
|
||||
>
|
||||
<span class="check-en" v-show="locale === 'en'">
|
||||
<span v-show="locale === 'en'" class="check-en">
|
||||
<IconifyIconOffline :icon="Check" />
|
||||
</span>
|
||||
English
|
||||
|
||||
@@ -1,18 +1,28 @@
|
||||
<script setup lang="ts">
|
||||
import path from "path";
|
||||
import { getConfig } from "@/config";
|
||||
import LinkItem from "./linkItem.vue";
|
||||
import { menuType } from "../../types";
|
||||
import extraIcon from "./extraIcon.vue";
|
||||
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 PropType,
|
||||
type CSSProperties,
|
||||
ref,
|
||||
toRaw,
|
||||
computed,
|
||||
useAttrs
|
||||
} from "vue";
|
||||
|
||||
import ArrowUp from "@iconify-icons/ep/arrow-up-bold";
|
||||
import EpArrowDown from "@iconify-icons/ep/arrow-down-bold";
|
||||
import ArrowLeft from "@iconify-icons/ep/arrow-left-bold";
|
||||
import ArrowRight from "@iconify-icons/ep/arrow-right-bold";
|
||||
|
||||
const attrs = useAttrs();
|
||||
const { layout, isCollapse, tooltipEffect, getDivStyle } = useNav();
|
||||
|
||||
const props = defineProps({
|
||||
@@ -29,29 +39,15 @@ const props = defineProps({
|
||||
}
|
||||
});
|
||||
|
||||
const getSpanStyle = computed((): CSSProperties => {
|
||||
return {
|
||||
width: "100%",
|
||||
textAlign: "center"
|
||||
};
|
||||
});
|
||||
|
||||
const getNoDropdownStyle = computed((): CSSProperties => {
|
||||
return {
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
alignItems: "center"
|
||||
};
|
||||
});
|
||||
|
||||
const getMenuTextStyle = computed(() => {
|
||||
return {
|
||||
overflow: "hidden",
|
||||
textOverflow: "ellipsis",
|
||||
outline: "none"
|
||||
};
|
||||
});
|
||||
|
||||
const getsubMenuIconStyle = computed((): CSSProperties => {
|
||||
const getSubMenuIconStyle = computed((): CSSProperties => {
|
||||
return {
|
||||
display: "flex",
|
||||
justifyContent: "center",
|
||||
@@ -60,45 +56,8 @@ const getsubMenuIconStyle = computed((): CSSProperties => {
|
||||
layout.value === "horizontal"
|
||||
? "0 5px 0 0"
|
||||
: isCollapse.value
|
||||
? "0 auto"
|
||||
: "0 5px 0 0"
|
||||
};
|
||||
});
|
||||
|
||||
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"
|
||||
: ""
|
||||
};
|
||||
? "0 auto"
|
||||
: "0 5px 0 0"
|
||||
};
|
||||
});
|
||||
|
||||
@@ -113,41 +72,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) => {
|
||||
@@ -182,131 +106,110 @@ function resolvePath(routePath) {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<el-menu-item
|
||||
<link-item
|
||||
v-if="
|
||||
hasOneShowingChild(props.item.children, props.item) &&
|
||||
(!onlyOneChild.children || onlyOneChild.noShowingChildren)
|
||||
"
|
||||
:index="resolvePath(onlyOneChild.path)"
|
||||
:class="{ 'submenu-title-noDropdown': !isNest }"
|
||||
:style="getNoDropdownStyle"
|
||||
:to="item"
|
||||
>
|
||||
<div
|
||||
v-if="toRaw(props.item.meta.icon)"
|
||||
class="sub-menu-icon"
|
||||
:style="getsubMenuIconStyle"
|
||||
<el-menu-item
|
||||
:index="resolvePath(onlyOneChild.path)"
|
||||
:class="{ 'submenu-title-noDropdown': !isNest }"
|
||||
:style="getNoDropdownStyle"
|
||||
v-bind="attrs"
|
||||
>
|
||||
<component
|
||||
:is="
|
||||
useRenderIcon(
|
||||
toRaw(onlyOneChild.meta.icon) ||
|
||||
(props.item.meta && toRaw(props.item.meta.icon))
|
||||
)
|
||||
<div
|
||||
v-if="toRaw(props.item.meta.icon)"
|
||||
class="sub-menu-icon"
|
||||
:style="getSubMenuIconStyle"
|
||||
>
|
||||
<component
|
||||
:is="
|
||||
useRenderIcon(
|
||||
toRaw(onlyOneChild.meta.icon) ||
|
||||
(props.item.meta && toRaw(props.item.meta.icon))
|
||||
)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<el-text
|
||||
v-if="
|
||||
(!props.item?.meta.icon &&
|
||||
isCollapse &&
|
||||
layout === 'vertical' &&
|
||||
props.item?.pathList?.length === 1) ||
|
||||
(!onlyOneChild.meta.icon &&
|
||||
isCollapse &&
|
||||
layout === 'mix' &&
|
||||
props.item?.pathList?.length === 2)
|
||||
"
|
||||
/>
|
||||
</div>
|
||||
<span
|
||||
v-if="
|
||||
!props.item?.meta.icon &&
|
||||
isCollapse &&
|
||||
layout === 'vertical' &&
|
||||
props.item?.pathList?.length === 1
|
||||
"
|
||||
:style="getSpanStyle"
|
||||
>
|
||||
{{ 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>
|
||||
<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"
|
||||
>
|
||||
<template #content>
|
||||
{{ transformI18n(onlyOneChild.meta.title) }}
|
||||
</template>
|
||||
<span
|
||||
ref="menuTextRef"
|
||||
:style="getMenuTextStyle"
|
||||
@mouseover="hoverMenu(onlyOneChild)"
|
||||
truncated
|
||||
class="!px-4 !text-inherit"
|
||||
>
|
||||
{{ transformI18n(onlyOneChild.meta.title) }}
|
||||
</el-text>
|
||||
|
||||
<template #title>
|
||||
<div :style="getDivStyle">
|
||||
<ReText
|
||||
:tippyProps="{
|
||||
offset: [0, -10],
|
||||
theme: tooltipEffect
|
||||
}"
|
||||
class="!text-inherit"
|
||||
>
|
||||
{{ transformI18n(onlyOneChild.meta.title) }}
|
||||
</span>
|
||||
</el-tooltip>
|
||||
<extraIcon :extraIcon="onlyOneChild.meta.extraIcon" />
|
||||
</div>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
|
||||
</ReText>
|
||||
<extraIcon :extraIcon="onlyOneChild.meta.extraIcon" />
|
||||
</div>
|
||||
</template>
|
||||
</el-menu-item>
|
||||
</link-item>
|
||||
<el-sub-menu
|
||||
v-else
|
||||
ref="subMenu"
|
||||
v-bind="expandCloseIcon"
|
||||
teleported
|
||||
:index="resolvePath(props.item.path)"
|
||||
v-bind="expandCloseIcon"
|
||||
>
|
||||
<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
|
||||
:style="getSubMenuDivStyle(props.item)"
|
||||
<ReText
|
||||
v-if="
|
||||
!(
|
||||
layout === 'vertical' &&
|
||||
isCollapse &&
|
||||
toRaw(props.item.meta.icon) &&
|
||||
props.item.parentId === null
|
||||
)
|
||||
"
|
||||
:tippyProps="{
|
||||
offset: [0, -10],
|
||||
theme: tooltipEffect
|
||||
}"
|
||||
: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
|
||||
v-for="child in props.item.children"
|
||||
:key="child.path"
|
||||
|
||||
@@ -18,7 +18,14 @@ const showLogo = ref(
|
||||
)?.showLogo ?? true
|
||||
);
|
||||
|
||||
const { device, pureApp, isCollapse, menuSelect, toggleSideBar } = useNav();
|
||||
const {
|
||||
device,
|
||||
pureApp,
|
||||
isCollapse,
|
||||
tooltipEffect,
|
||||
menuSelect,
|
||||
toggleSideBar
|
||||
} = useNav();
|
||||
|
||||
const subMenuData = ref([]);
|
||||
|
||||
@@ -80,7 +87,7 @@ onBeforeUnmount(() => {
|
||||
<template>
|
||||
<div
|
||||
v-loading="loading"
|
||||
:class="['sidebar-container', showLogo ? 'has-logo' : '']"
|
||||
:class="['sidebar-container', showLogo ? 'has-logo' : 'no-logo']"
|
||||
>
|
||||
<Logo v-if="showLogo" :collapse="isCollapse" />
|
||||
<el-scrollbar
|
||||
@@ -91,10 +98,12 @@ onBeforeUnmount(() => {
|
||||
router
|
||||
unique-opened
|
||||
mode="vertical"
|
||||
popper-class="pure-scrollbar"
|
||||
class="outer-most select-none"
|
||||
:collapse="isCollapse"
|
||||
:default-active="defaultActive"
|
||||
:collapse-transition="false"
|
||||
:popper-effect="tooltipEffect"
|
||||
:default-active="defaultActive"
|
||||
>
|
||||
<sidebar-item
|
||||
v-for="routes in menuData"
|
||||
|
||||
Reference in New Issue
Block a user