diff --git a/packages/components/menu/src/menu.vue b/packages/components/menu/src/menu.vue index d9e9cc5950..4eb6e921a5 100644 --- a/packages/components/menu/src/menu.vue +++ b/packages/components/menu/src/menu.vue @@ -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) diff --git a/packages/components/menu/src/submenu.vue b/packages/components/menu/src/submenu.vue index b208ce6ef4..17e7c55f18 100644 --- a/packages/components/menu/src/submenu.vue +++ b/packages/components/menu/src/submenu.vue @@ -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 || '', } diff --git a/packages/theme-chalk/src/menu.scss b/packages/theme-chalk/src/menu.scss index 61b02e4796..25f66fea38 100644 --- a/packages/theme-chalk/src/menu.scss +++ b/packages/theme-chalk/src/menu.scss @@ -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; }