fix: [el-menu] using v-for causing render loop (#3617)

* fix: [el-menu] using v-for causing render loop

* fix: [el-menu] using v-for causing render loop

* perf: improve perf

Co-authored-by: Kevin <sxzz@sxzz.moe>
This commit is contained in:
啝裳 2021-09-24 21:08:23 +08:00 committed by GitHub
parent 3138dea797
commit 4dd3806f47
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -9,7 +9,6 @@ import {
isRef,
h,
withDirectives,
nextTick,
} from 'vue'
import { Resize } from '@element-plus/directives'
import Menubar from '@element-plus/utils/menu/menu-bar'
@ -293,55 +292,51 @@ export default defineComponent({
let slot = slots.default?.() ?? []
const showMore = []
if (props.mode === 'horizontal') {
if (props.mode === 'horizontal' && menu.value) {
const items = Array.from(
(menu.value as Node | undefined)?.childNodes ?? []
).filter(
(item) => item.nodeName !== '#text' || item.nodeValue
) as HTMLElement[]
const originalSlot = flattedChildren(slot)
if (items.length === originalSlot.length) {
const moreItemWidth = 64
const paddingLeft = parseInt(
getComputedStyle(menu.value).paddingLeft,
10
)
const paddingRight = parseInt(
getComputedStyle(menu.value).paddingRight,
10
)
const menuWidth = menu.value.clientWidth - paddingLeft - paddingRight
let calcWidth = 0
let sliceIndex = 0
items.forEach((item, index) => {
calcWidth += item.offsetWidth || 0
if (calcWidth <= menuWidth - moreItemWidth) {
sliceIndex = index + 1
}
})
const defaultSlot = originalSlot.slice(0, sliceIndex)
const moreSlot = originalSlot.slice(sliceIndex)
if (moreSlot?.length) {
slot = defaultSlot
showMore.push(
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,
}
)
)
const moreItemWidth = 64
const paddingLeft = parseInt(
getComputedStyle(menu.value).paddingLeft,
10
)
const paddingRight = parseInt(
getComputedStyle(menu.value).paddingRight,
10
)
const menuWidth = menu.value.clientWidth - paddingLeft - paddingRight
let calcWidth = 0
let sliceIndex = 0
items.forEach((item, index) => {
calcWidth += item.offsetWidth || 0
if (calcWidth <= menuWidth - moreItemWidth) {
sliceIndex = index + 1
}
} else {
nextTick(() => instance.proxy.$forceUpdate())
})
const defaultSlot = originalSlot.slice(0, sliceIndex)
const moreSlot = originalSlot.slice(sliceIndex)
if (moreSlot?.length) {
slot = defaultSlot
showMore.push(
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,
}
)
)
}
}