Comments (9)
提供截图和复现仓库 而不是压缩包
from vue-pure-admin.
from vue-pure-admin.
https://yiming_chang.gitee.io/vue-pure-admin/#/components/message 地址为在线演示地址
from vue-pure-admin.
这并非平台问题 el-menu
折叠后本身就不支持滚动 或许你可以尝试用样式使其支持
from vue-pure-admin.
基于昨天的问题我询问了element的官方, 他们给出了一个可行的解决方案, 即在el-menu-item
组件的外层嵌套一个 el-menu-item-group
并给组件设置max-height
与overflow-y
属性可以解决这个问题, 可我在Pure Admin的源码中并未发现相关的处理, 在我看来这确实属于一个代码的bug,若能做出相应更改的话, 会很棒
from vue-pure-admin.
Welcome to PR
from vue-pure-admin.
将 src/layout/components/sidebar/sidebarItem.vue
文件改为下面代码
<script setup lang="ts">
import path from "path";
import { getConfig } from "@/config";
import { menuType } from "../../types";
import extraIcon from "./extraIcon.vue";
import { useWindowSize } from "@vueuse/core";
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 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 { height } = useWindowSize();
const { layout, isCollapse, tooltipEffect, getDivStyle } = useNav();
const props = defineProps({
item: {
type: Object as PropType<menuType>
},
isNest: {
type: Boolean,
default: false
},
basePath: {
type: String,
default: ""
}
});
const getSpanStyle = computed((): CSSProperties => {
return {
width: "100%",
textAlign: "center"
};
});
const getNoDropdownStyle = computed((): CSSProperties => {
return {
display: "flex",
alignItems: "center"
};
});
const getMenuTextStyle = computed(() => {
return {
overflow: "hidden",
textOverflow: "ellipsis",
outline: "none"
};
});
const getsubMenuIconStyle = computed((): CSSProperties => {
return {
display: "flex",
justifyContent: "center",
alignItems: "center",
margin:
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"
: ""
};
};
});
const expandCloseIcon = computed(() => {
if (!getConfig()?.MenuArrowIconNoTransition) return "";
return {
"expand-close-icon": useRenderIcon(EpArrowDown),
"expand-open-icon": useRenderIcon(ArrowUp),
"collapse-close-icon": useRenderIcon(ArrowRight),
"collapse-open-icon": useRenderIcon(ArrowLeft)
};
});
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) => {
onlyOneChild.value = item;
return true;
});
if (showingChildren[0]?.meta?.showParent) {
return false;
}
if (showingChildren.length === 1) {
return true;
}
if (showingChildren.length === 0) {
onlyOneChild.value = { ...parent, path: "", noShowingChildren: true };
return true;
}
return false;
}
function resolvePath(routePath) {
const httpReg = /^http(s?):\/\//;
if (httpReg.test(routePath) || httpReg.test(props.basePath)) {
return routePath || props.basePath;
} else {
// 使用path.posix.resolve替代path.resolve 避免windows环境下使用electron出现盘符问题
return path.posix.resolve(props.basePath, routePath);
}
}
</script>
<template>
<el-menu-item
v-if="
hasOneShowingChild(props.item.children, props.item) &&
(!onlyOneChild.children || onlyOneChild.noShowingChildren)
"
:index="resolvePath(onlyOneChild.path)"
:class="{ 'submenu-title-noDropdown': !isNest }"
:style="getNoDropdownStyle"
>
<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>
<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)"
>
{{ transformI18n(onlyOneChild.meta.title) }}
</span>
</el-tooltip>
<extraIcon :extraIcon="onlyOneChild.meta.extraIcon" />
</div>
</template>
</el-menu-item>
<el-sub-menu
v-else
ref="subMenu"
v-bind="expandCloseIcon"
:index="resolvePath(props.item.path)"
>
<template #title>
<div
v-if="toRaw(props.item.meta.icon)"
: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)"
v-if="
!(
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>
</template>
<el-scrollbar
v-if="layout !== 'horizontal'"
class="sidebar-scrollbar"
:max-height="`${height - 18}px`"
>
<sidebar-item
v-for="child in props.item.children"
:key="child.path"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
class="nest-menu"
/>
</el-scrollbar>
<template v-else>
<sidebar-item
v-for="child in props.item.children"
:key="child.path"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
class="nest-menu"
/>
</template>
</el-sub-menu>
</template>
<style scoped>
.sidebar-scrollbar {
overflow: visible;
}
</style>
但这并不是最优解,如果el-menu
折叠后,本身就支持el-scrollbar
会更好
from vue-pure-admin.
改动对比
from vue-pure-admin.
from vue-pure-admin.
Related Issues (20)
- 如何在verical布局模式下添加一个layout只有navbar,隐藏sidebar的路由页面 HOT 1
- 无法实现代码混淆 HOT 1
- get请求无法传递参数
- 函数式弹窗,点击取消按钮, 延时关闭无效 HOT 1
- 文档和演示站打不开了,提示404 HOT 8
- 大佬,什么时候实现基于前端实现的权限 HOT 1
- 请升级vue版本 HOT 1
- 登录处理建议 HOT 1
- 不算bug,一丢丢文档问题 HOT 1
- 表格adaptive属性在列表初始化隐藏的时候高度异常 HOT 3
- 📢通知!文档站和完整版预览站地址更换!!!
- `segmented`分段控制器尺寸变化问题及 `Element Plus 2.7.0` 新分段器的应用 HOT 3
- 【不是bug】请教一下关于Redialog组件渲染问题 HOT 1
- 菜单中点击外链会跳转两次 HOT 1
- 菜单中点击外链会跳转两次(补充复现条件)
- 后端菜单无法展示到页面上 HOT 1
- 登录页中免登录勾选框获取焦点后显示不全 HOT 1
- [PR] 我抽离了各种布局模式下的语言选择器为公共组件 HOT 1
- 📢 通知:`issues`通道已关闭!反馈问题请走网易邮箱
- 如何删除title中的favicon.ico 图标 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from vue-pure-admin.