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 () => {
|
const updateFilteredSlot = async () => {
|
||||||
filteredSlot.value = slots.default?.()
|
filteredSlot.value = slots.default?.()
|
||||||
await nextTick()
|
await nextTick()
|
||||||
if (props.mode === 'horizontal') {
|
if (props.mode === 'horizontal') {
|
||||||
const items = Array.from(menu.value.childNodes).filter((item: HTMLElement) => item.nodeName !== '#text' || item.nodeValue) as [HTMLElement]
|
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 moreItemWidth = 64
|
||||||
const paddingLeft = parseInt(getComputedStyle(menu.value).paddingLeft)
|
const paddingLeft = parseInt(getComputedStyle(menu.value).paddingLeft)
|
||||||
const paddingRight = parseInt(getComputedStyle(menu.value).paddingRight)
|
const paddingRight = parseInt(getComputedStyle(menu.value).paddingRight)
|
||||||
@ -241,13 +255,14 @@ export default defineComponent({
|
|||||||
sliceIndex = index + 1
|
sliceIndex = index + 1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
const defaultSlot = slots.default?.().slice(0, sliceIndex)
|
const defaultSlot = originalSlot.slice(0, sliceIndex)
|
||||||
const moreSlot = slots.default?.().slice(sliceIndex)
|
const moreSlot = originalSlot.slice(sliceIndex)
|
||||||
if (moreSlot?.length) {
|
if (moreSlot?.length) {
|
||||||
filteredSlot.value = [
|
filteredSlot.value = [
|
||||||
...defaultSlot,
|
...defaultSlot,
|
||||||
h(ElSubMenu, {
|
h(ElSubMenu, {
|
||||||
index: 'sub-menu-more',
|
index: 'sub-menu-more',
|
||||||
|
class: 'el-sub-menu__hide-arrow',
|
||||||
}, {
|
}, {
|
||||||
title: () => h('i', { class: ['el-icon-more', 'el-sub-menu__icon-more'] }),
|
title: () => h('i', { class: ['el-icon-more', 'el-sub-menu__icon-more'] }),
|
||||||
default: () => moreSlot,
|
default: () => moreSlot,
|
||||||
@ -259,10 +274,8 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleResize = () => {
|
const handleResize = () => {
|
||||||
if (props.mode === 'horizontal') {
|
|
||||||
updateFilteredSlot()
|
updateFilteredSlot()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// watch
|
// watch
|
||||||
watch(() => slots.default?.(), () => {
|
watch(() => slots.default?.(), () => {
|
||||||
@ -348,6 +361,7 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
|
const directives = this.mode === 'horizontal' ? [[Resize, this.handleResize]] : []
|
||||||
const menu = withDirectives(h('ul', {
|
const menu = withDirectives(h('ul', {
|
||||||
key: String(this.collapse),
|
key: String(this.collapse),
|
||||||
role: 'menubar',
|
role: 'menubar',
|
||||||
@ -358,7 +372,7 @@ export default defineComponent({
|
|||||||
'el-menu--horizontal': this.mode === 'horizontal',
|
'el-menu--horizontal': this.mode === 'horizontal',
|
||||||
'el-menu--collapse': this.collapse,
|
'el-menu--collapse': this.collapse,
|
||||||
},
|
},
|
||||||
}, [this.filteredSlot]), [[Resize, this.handleResize]])
|
}, [this.filteredSlot]), directives)
|
||||||
|
|
||||||
if (this.collapseTransition) {
|
if (this.collapseTransition) {
|
||||||
return h(ElMenuCollapseTransition, () => menu)
|
return h(ElMenuCollapseTransition, () => menu)
|
||||||
|
@ -89,7 +89,6 @@ export default defineComponent({
|
|||||||
? 'el-icon-arrow-down'
|
? 'el-icon-arrow-down'
|
||||||
: 'el-icon-arrow-right'
|
: 'el-icon-arrow-right'
|
||||||
})
|
})
|
||||||
const showSubmenuTitleIcon = computed(() => mode.value === 'vertical' || !isFirstLevel.value)
|
|
||||||
const isFirstLevel = computed(() => {
|
const isFirstLevel = computed(() => {
|
||||||
let isFirstLevel = true
|
let isFirstLevel = true
|
||||||
let parent = instance.parent
|
let parent = instance.parent
|
||||||
@ -333,7 +332,6 @@ export default defineComponent({
|
|||||||
menuTransitionName,
|
menuTransitionName,
|
||||||
fallbackPlacements,
|
fallbackPlacements,
|
||||||
submenuTitleIcon,
|
submenuTitleIcon,
|
||||||
showSubmenuTitleIcon,
|
|
||||||
appendToBody,
|
appendToBody,
|
||||||
|
|
||||||
handleClick,
|
handleClick,
|
||||||
@ -352,14 +350,12 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
render() {
|
render() {
|
||||||
const titleTag = [this.$slots.title?.()]
|
|
||||||
if (this.showSubmenuTitleIcon) {
|
const titleTag = [
|
||||||
titleTag.push(
|
this.$slots.title?.(),
|
||||||
h('i', {
|
h('i', {
|
||||||
class: ['el-sub-menu__icon-arrow', this.submenuTitleIcon],
|
class: ['el-sub-menu__icon-arrow', this.submenuTitleIcon],
|
||||||
}, null),
|
}, null)]
|
||||||
)
|
|
||||||
}
|
|
||||||
const ulStyle = {
|
const ulStyle = {
|
||||||
backgroundColor: this.rootProps.backgroundColor || '',
|
backgroundColor: this.rootProps.backgroundColor || '',
|
||||||
}
|
}
|
||||||
|
@ -252,6 +252,11 @@
|
|||||||
padding: 0 45px;
|
padding: 0 45px;
|
||||||
min-width: 200px;
|
min-width: 200px;
|
||||||
}
|
}
|
||||||
|
@include e(hide-arrow) {
|
||||||
|
.#{$namespace}-sub-menu__icon-arrow {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
@include e(icon-more) {
|
@include e(icon-more) {
|
||||||
margin-right: 0 !important;
|
margin-right: 0 !important;
|
||||||
}
|
}
|
||||||
@ -303,8 +308,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.horizontal-collapse-transition
|
.horizontal-collapse-transition
|
||||||
.#{$namespace}-sub-menu__title
|
.#{$namespace}-sub-menu__title
|
||||||
.#{$namespace}-sub-menu__icon-arrow {
|
.#{$namespace}-sub-menu__icon-arrow {
|
||||||
transition: var(--el-transition-duration-fast);
|
transition: var(--el-transition-duration-fast);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user