mirror of
https://github.com/element-plus/element-plus.git
synced 2024-12-21 02:50:11 +08:00
perf: perf menu add back arrow-icon and overflow (#3167)
* perf: perf menu add back arrow-icon and overflow * perf: optimize resize
This commit is contained in:
parent
eacd21f118
commit
614c09eead
@ -223,12 +223,26 @@ export default defineComponent({
|
||||
}
|
||||
}
|
||||
|
||||
const flattedChildren = children => {
|
||||
const temp = Array.isArray(children) ? children : [children]
|
||||
const res = []
|
||||
temp.forEach(child => {
|
||||
if (Array.isArray(child.children)) {
|
||||
res.push(...flattedChildren(child.children))
|
||||
} else {
|
||||
res.push(child)
|
||||
}
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
const updateFilteredSlot = async () => {
|
||||
filteredSlot.value = slots.default?.()
|
||||
await nextTick()
|
||||
if (props.mode === 'horizontal') {
|
||||
const items = Array.from(menu.value.childNodes).filter((item: HTMLElement) => item.nodeName !== '#text' || item.nodeValue) as [HTMLElement]
|
||||
if (items.length === slots.default?.().length) {
|
||||
const originalSlot = flattedChildren(slots.default?.()) || []
|
||||
if (items.length === originalSlot.length) {
|
||||
const moreItemWidth = 64
|
||||
const paddingLeft = parseInt(getComputedStyle(menu.value).paddingLeft)
|
||||
const paddingRight = parseInt(getComputedStyle(menu.value).paddingRight)
|
||||
@ -241,13 +255,14 @@ export default defineComponent({
|
||||
sliceIndex = index + 1
|
||||
}
|
||||
})
|
||||
const defaultSlot = slots.default?.().slice(0, sliceIndex)
|
||||
const moreSlot = slots.default?.().slice(sliceIndex)
|
||||
const defaultSlot = originalSlot.slice(0, sliceIndex)
|
||||
const moreSlot = originalSlot.slice(sliceIndex)
|
||||
if (moreSlot?.length) {
|
||||
filteredSlot.value = [
|
||||
...defaultSlot,
|
||||
h(ElSubMenu, {
|
||||
index: 'sub-menu-more',
|
||||
class: 'el-sub-menu__hide-arrow',
|
||||
}, {
|
||||
title: () => h('i', { class: ['el-icon-more', 'el-sub-menu__icon-more'] }),
|
||||
default: () => moreSlot,
|
||||
@ -259,9 +274,7 @@ export default defineComponent({
|
||||
}
|
||||
|
||||
const handleResize = () => {
|
||||
if (props.mode === 'horizontal') {
|
||||
updateFilteredSlot()
|
||||
}
|
||||
updateFilteredSlot()
|
||||
}
|
||||
|
||||
// watch
|
||||
@ -348,6 +361,7 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const directives = this.mode === 'horizontal' ? [[Resize, this.handleResize]] : []
|
||||
const menu = withDirectives(h('ul', {
|
||||
key: String(this.collapse),
|
||||
role: 'menubar',
|
||||
@ -358,7 +372,7 @@ export default defineComponent({
|
||||
'el-menu--horizontal': this.mode === 'horizontal',
|
||||
'el-menu--collapse': this.collapse,
|
||||
},
|
||||
}, [this.filteredSlot]), [[Resize, this.handleResize]])
|
||||
}, [this.filteredSlot]), directives)
|
||||
|
||||
if (this.collapseTransition) {
|
||||
return h(ElMenuCollapseTransition, () => menu)
|
||||
|
@ -89,7 +89,6 @@ export default defineComponent({
|
||||
? 'el-icon-arrow-down'
|
||||
: 'el-icon-arrow-right'
|
||||
})
|
||||
const showSubmenuTitleIcon = computed(() => mode.value === 'vertical' || !isFirstLevel.value)
|
||||
const isFirstLevel = computed(() => {
|
||||
let isFirstLevel = true
|
||||
let parent = instance.parent
|
||||
@ -333,7 +332,6 @@ export default defineComponent({
|
||||
menuTransitionName,
|
||||
fallbackPlacements,
|
||||
submenuTitleIcon,
|
||||
showSubmenuTitleIcon,
|
||||
appendToBody,
|
||||
|
||||
handleClick,
|
||||
@ -352,14 +350,12 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
render() {
|
||||
const titleTag = [this.$slots.title?.()]
|
||||
if (this.showSubmenuTitleIcon) {
|
||||
titleTag.push(
|
||||
h('i', {
|
||||
class: ['el-sub-menu__icon-arrow', this.submenuTitleIcon],
|
||||
}, null),
|
||||
)
|
||||
}
|
||||
|
||||
const titleTag = [
|
||||
this.$slots.title?.(),
|
||||
h('i', {
|
||||
class: ['el-sub-menu__icon-arrow', this.submenuTitleIcon],
|
||||
}, null)]
|
||||
const ulStyle = {
|
||||
backgroundColor: this.rootProps.backgroundColor || '',
|
||||
}
|
||||
|
@ -14,8 +14,8 @@
|
||||
cursor: pointer;
|
||||
position: relative;
|
||||
transition: border-color var(--el-transition-duration),
|
||||
background-color var(--el-transition-duration),
|
||||
color var(--el-transition-duration);
|
||||
background-color var(--el-transition-duration),
|
||||
color var(--el-transition-duration);
|
||||
box-sizing: border-box;
|
||||
white-space: nowrap;
|
||||
|
||||
@ -252,6 +252,11 @@
|
||||
padding: 0 45px;
|
||||
min-width: 200px;
|
||||
}
|
||||
@include e(hide-arrow) {
|
||||
.#{$namespace}-sub-menu__icon-arrow {
|
||||
display: none !important;
|
||||
}
|
||||
}
|
||||
@include e(icon-more) {
|
||||
margin-right: 0 !important;
|
||||
}
|
||||
@ -303,8 +308,8 @@
|
||||
}
|
||||
|
||||
.horizontal-collapse-transition
|
||||
.#{$namespace}-sub-menu__title
|
||||
.#{$namespace}-sub-menu__icon-arrow {
|
||||
.#{$namespace}-sub-menu__title
|
||||
.#{$namespace}-sub-menu__icon-arrow {
|
||||
transition: var(--el-transition-duration-fast);
|
||||
opacity: 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user