Skip to content

Commit 8c94b78

Browse files
committed
fix: menu overflowed error #3262
1 parent f5cf7e0 commit 8c94b78

File tree

6 files changed

+39
-12
lines changed

6 files changed

+39
-12
lines changed

components/menu/__tests__/index.test.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ describe('Menu', () => {
477477
}, 500);
478478
});
479479

480-
fit('horizontal', async () => {
480+
it('horizontal', async () => {
481481
const wrapper = mount(
482482
{
483483
render() {

components/vc-menu/DOMWrap.jsx

+23-7
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@ import SubMenu from './SubMenu';
44
import BaseMixin from '../_util/BaseMixin';
55
import { getWidth, setStyle, menuAllProps } from './util';
66
import { cloneElement } from '../_util/vnode';
7-
import { getPropsData, getAllProps, getSlot, findDOMNode } from '../_util/props-util';
7+
import { getAllProps, getSlot, findDOMNode } from '../_util/props-util';
88

99
const MENUITEM_OVERFLOWED_CLASSNAME = 'menuitem-overflowed';
1010
const FLOAT_PRECISION_ADJUST = 0.5;
11+
const MENUITEM_OVERFLOWED_UNI_KEY = 'MENUITEM_OVERFLOWED_UNI_KEY';
12+
const MENUITEM_OVERFLOWED_UNI_KEYS = [MENUITEM_OVERFLOWED_UNI_KEY];
1113

1214
const DOMWrap = {
1315
name: 'DOMWrap',
@@ -136,6 +138,7 @@ const DOMWrap = {
136138
class: `${prefixCls}-overflowed-submenu`,
137139
key,
138140
style,
141+
isOverflowedSubMenu: true,
139142
};
140143
return <SubMenu {...subMenuProps}>{overflowedItems}</SubMenu>;
141144
},
@@ -227,7 +230,8 @@ const DOMWrap = {
227230
const className = this.$attrs.class || '';
228231
return (children || []).reduce((acc, childNode, index) => {
229232
let item = childNode;
230-
const eventKey = getPropsData(childNode).eventKey;
233+
const { extraProps = {} } = item.props || {};
234+
const { eventKey } = extraProps;
231235
if (this.mode === 'horizontal') {
232236
let overflowed = this.getOverflowedSubMenuItem(eventKey, []);
233237
if (
@@ -239,21 +243,33 @@ const DOMWrap = {
239243
childNode,
240244
// 这里修改 eventKey 是为了防止隐藏状态下还会触发 openkeys 事件
241245
{
242-
style: { display: 'none' },
243-
eventKey: `${eventKey}-hidden`,
244-
class: MENUITEM_OVERFLOWED_CLASSNAME,
246+
extraProps: {
247+
...extraProps,
248+
style: { display: 'none' },
249+
eventKey: `${eventKey}-hidden`,
250+
class: MENUITEM_OVERFLOWED_CLASSNAME,
251+
parentUniKey: MENUITEM_OVERFLOWED_UNI_KEY,
252+
parentUniKeys: MENUITEM_OVERFLOWED_UNI_KEYS,
253+
},
245254
},
246255
);
247256
}
248257
if (index === lastVisibleIndex + 1) {
249258
this.overflowedItems = children.slice(lastVisibleIndex + 1).map(c => {
259+
const { extraProps = {} } = c.props || {};
260+
const { eventKey } = extraProps;
250261
return cloneElement(
251262
c,
252263
// children[index].key will become '.$key' in clone by default,
253264
// we have to overwrite with the correct key explicitly
254265
{
255-
key: getPropsData(c).eventKey,
256-
mode: 'vertical-left',
266+
extraProps: {
267+
...extraProps,
268+
key: eventKey,
269+
mode: 'vertical-left',
270+
parentUniKey: MENUITEM_OVERFLOWED_UNI_KEY,
271+
parentUniKeys: MENUITEM_OVERFLOWED_UNI_KEYS,
272+
},
257273
},
258274
);
259275
});

components/vc-menu/FunctionProvider.jsx

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { propTypes } from '../vc-progress/src/types';
44
export const injectExtraPropsKey = Symbol();
55
const FunctionProvider = {
66
inheritAttrs: false,
7+
isMenuProvider: true,
78
props: {
89
extraProps: propTypes.object,
910
},

components/vc-menu/Menu.jsx

+4-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
toRaw,
1414
watch,
1515
} from 'vue';
16+
import { isEqual } from 'lodash-es';
1617

1718
const Menu = {
1819
name: 'Menu',
@@ -62,7 +63,9 @@ const Menu = {
6263
.reduce((allKeys, { parentUniKeys = [] }) => {
6364
return [...allKeys, ...toRaw(parentUniKeys)];
6465
}, []);
65-
selectedParentUniKeys.value = keys || [];
66+
if (!isEqual(selectedParentUniKeys.value, keys)) {
67+
selectedParentUniKeys.value = keys || [];
68+
}
6669
});
6770
const store = reactive({
6871
selectedKeys,

components/vc-menu/SubMenu.jsx

+4-2
Original file line numberDiff line numberDiff line change
@@ -75,11 +75,14 @@ const SubMenu = defineComponent({
7575
theme: PropTypes.string,
7676
parentUniKeys: PropTypes.array.def(() => []),
7777
parentUniKey: PropTypes.string,
78+
isOverflowedSubMenu: PropTypes.looseBool.def(false),
7879
},
7980

8081
isSubMenu: true,
8182
setup(props) {
82-
const uniKey = `sub_menu_${++indexGuid}`;
83+
const uniKey = props.isOverflowedSubMenu
84+
? 'MENUITEM_OVERFLOWED_UNI_KEY'
85+
: `sub_menu_${++indexGuid}`;
8386
const store = inject('menuStore', () => ({}));
8487
onMounted(() => {
8588
store.addChildrenInfo(
@@ -439,7 +442,6 @@ const SubMenu = defineComponent({
439442
[this.getDisabledClassName()]: props.disabled,
440443
[this.getSelectedClassName()]: this.isChildrenSelected || this.isChildrenSelected2(),
441444
};
442-
443445
if (!this.internalMenuId) {
444446
if (props.eventKey) {
445447
this.internalMenuId = `${props.eventKey}$Menu`;

components/vc-menu/util.js

+6-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@ export function loopMenuItemRecursively(children, keys, ret) {
4040
if (construct && isObject(construct)) {
4141
if (
4242
!construct ||
43-
!(construct.isSubMenu || construct.isMenuItem || construct.isMenuItemGroup)
43+
!(
44+
construct.isSubMenu ||
45+
construct.isMenuItem ||
46+
construct.isMenuItemGroup ||
47+
construct.isMenuProvider
48+
)
4449
) {
4550
return;
4651
}

0 commit comments

Comments
 (0)