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:
kooriookami 2021-09-01 15:43:57 +08:00 committed by GitHub
parent eacd21f118
commit 614c09eead
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 36 additions and 21 deletions

View File

@ -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)

View File

@ -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 || '',
} }

View File

@ -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;
} }