Skip to content

Commit 1dcd93f

Browse files
authored
Perf menu (#3177)
* fix: menu parent dom select class not work * perf: ease-in-out update
1 parent e7fbaac commit 1dcd93f

File tree

7 files changed

+235
-38
lines changed

7 files changed

+235
-38
lines changed

components/menu/__tests__/__snapshots__/demo.test.js.snap

+191-23
Large diffs are not rendered by default.

components/menu/index.tsx

-1
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,6 @@ const Menu = defineComponent({
276276
onMouseenter: this.handleMouseEnter,
277277
onTransitionend: this.handleTransitionEnd,
278278
children: getSlot(this),
279-
openTransitionName: '', //issue解决后可去掉openTransitionName https://github.com/vuejs/vue-next/issues/1412
280279
};
281280
if (!hasProp(this, 'selectedKeys')) {
282281
delete menuProps.selectedKeys;

components/style/themes/default.less

+1-1
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@
9898
@ease-base-in: cubic-bezier(0.9, 0, 0.3, 0.7);
9999
@ease-out: cubic-bezier(0.215, 0.61, 0.355, 1);
100100
@ease-in: cubic-bezier(0.55, 0.055, 0.675, 0.19);
101-
@ease-in-out: cubic-bezier(0.645, 0.045, 0.355, 1);
101+
@ease-in-out: cubic-bezier(0.25, 0.8, 0.5, 1);
102102
@ease-out-back: cubic-bezier(0.12, 0.4, 0.29, 1.46);
103103
@ease-in-back: cubic-bezier(0.71, -0.46, 0.88, 0.6);
104104
@ease-in-out-back: cubic-bezier(0.71, -0.46, 0.29, 1.46);

components/vc-menu/MenuItem.jsx

+11-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,11 @@ const MenuItem = {
4242
// invoke customized ref to expose component to mixin
4343
this.callRef();
4444
},
45+
mounted() {
46+
this.updateParentMenuSelectedStatus();
47+
},
4548
updated() {
49+
this.updateParentMenuSelectedStatus();
4650
this.$nextTick(() => {
4751
const { active, parentMenu, eventKey } = this;
4852
if (!this.prevActive && active && (!parentMenu || !parentMenu[`scrolled-${eventKey}`])) {
@@ -58,10 +62,16 @@ const MenuItem = {
5862
this.callRef();
5963
},
6064
beforeUnmount() {
65+
this.updateParentMenuSelectedStatus(false);
6166
const props = this.$props;
6267
this.__emit('destroy', props.eventKey);
6368
},
6469
methods: {
70+
updateParentMenuSelectedStatus(status = this.isSelected) {
71+
if (this.parentMenu && this.parentMenu.setChildrenSelectedStatus) {
72+
this.parentMenu.setChildrenSelectedStatus(this.eventKey, status);
73+
}
74+
},
6575
onKeyDown(e) {
6676
const keyCode = e.keyCode;
6777
if (keyCode === KeyCode.ENTER) {
@@ -99,7 +109,7 @@ const MenuItem = {
99109
const info = {
100110
key: eventKey,
101111
keyPath: [eventKey],
102-
item: this,
112+
item: { ...this.$props },
103113
domEvent: e,
104114
};
105115

components/vc-menu/SubMenu.jsx

+30-10
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import placements from './placements';
99
import BaseMixin from '../_util/BaseMixin';
1010
import { getComponent, filterEmpty, getSlot, splitAttrs, findDOMNode } from '../_util/props-util';
1111
import { requestAnimationTimeout, cancelAnimationTimeout } from '../_util/requestAnimationTimeout';
12-
import { noop, loopMenuItemRecursively, getMenuIdFromSubMenuEventKey } from './util';
12+
import { noop, getMenuIdFromSubMenuEventKey } from './util';
1313
import { getTransitionProps, Transition } from '../_util/transition';
1414
import { injectExtraPropsKey } from './FunctionProvider';
1515

@@ -49,7 +49,7 @@ const SubMenu = {
4949
triggerSubMenuAction: PropTypes.string,
5050
popupClassName: PropTypes.string,
5151
getPopupContainer: PropTypes.func,
52-
forceSubMenuRender: PropTypes.looseBool,
52+
forceSubMenuRender: PropTypes.looseBool.def(true),
5353
openAnimation: PropTypes.oneOfType([PropTypes.string, PropTypes.object]),
5454
disabled: PropTypes.looseBool,
5555
subMenuOpenDelay: PropTypes.number.def(0.1),
@@ -100,21 +100,30 @@ const SubMenu = {
100100
this.subMenuTitle = undefined;
101101
return {
102102
// defaultActiveFirst: false,
103+
childrenSelectedStatus: {},
103104
};
104105
},
106+
computed: {
107+
isChildrenSelected() {
108+
return Object.values(this.childrenSelectedStatus).find(status => status);
109+
},
110+
},
105111
mounted() {
106112
this.$nextTick(() => {
107113
this.handleUpdated();
108114
});
115+
this.updateParentMenuSelectedStatus();
109116
},
110117

111118
updated() {
112119
this.$nextTick(() => {
113120
this.handleUpdated();
114121
});
122+
this.updateParentMenuSelectedStatus();
115123
},
116124

117125
beforeUnmount() {
126+
this.updateParentMenuSelectedStatus(false);
118127
const { eventKey } = this;
119128
this.__emit('destroy', eventKey);
120129

@@ -131,6 +140,18 @@ const SubMenu = {
131140
}
132141
},
133142
methods: {
143+
updateParentMenuSelectedStatus(status = this.isChildrenSelected) {
144+
if (this.parentMenu && this.parentMenu.setChildrenSelectedStatus) {
145+
this.parentMenu.setChildrenSelectedStatus(this.eventKey, status);
146+
}
147+
},
148+
setChildrenSelectedStatus(key, status) {
149+
if (!status) {
150+
delete this.childrenSelectedStatus[key];
151+
} else {
152+
this.childrenSelectedStatus[key] = status;
153+
}
154+
},
134155
handleUpdated() {
135156
const { mode, parentMenu, manualRef } = this;
136157

@@ -310,11 +331,11 @@ const SubMenu = {
310331
}
311332
},
312333

313-
isChildrenSelected(children) {
314-
const ret = { find: false };
315-
loopMenuItemRecursively(children, this.$props.selectedKeys, ret);
316-
return ret.find;
317-
},
334+
// isChildrenSelected(children) {
335+
// const ret = { find: false };
336+
// loopMenuItemRecursively(children, this.$props.selectedKeys, ret);
337+
// return ret.find;
338+
// },
318339
// isOpen () {
319340
// return this.$props.openKeys.indexOf(this.$props.eventKey) !== -1
320341
// },
@@ -412,7 +433,6 @@ const SubMenu = {
412433
render() {
413434
const props = { ...this.$props, ...this.$attrs };
414435
const { onEvents } = splitAttrs(props);
415-
const { rootPrefixCls } = this;
416436
const isOpen = props.isOpen;
417437
const prefixCls = this.getPrefixCls();
418438
const isInlineMode = props.mode === 'inline';
@@ -425,7 +445,7 @@ const SubMenu = {
425445
[this.getOpenClassName()]: isOpen,
426446
[this.getActiveClassName()]: props.active || (isOpen && !isInlineMode),
427447
[this.getDisabledClassName()]: props.disabled,
428-
[this.getSelectedClassName()]: this.isChildrenSelected(childrenTemp),
448+
[this.getSelectedClassName()]: this.isChildrenSelected,
429449
};
430450

431451
if (!this.internalMenuId) {
@@ -498,7 +518,7 @@ const SubMenu = {
498518
const popupPlacement = popupPlacementMap[props.mode];
499519
const popupAlign = props.popupOffset ? { offset: props.popupOffset } : {};
500520
let popupClassName = props.mode === 'inline' ? '' : props.popupClassName || '';
501-
popupClassName = `${prefixCls}-popup ${rootPrefixCls} ${popupClassName}`;
521+
popupClassName = `${prefixCls}-popup ${popupClassName}`;
502522
const liProps = {
503523
...omit(onEvents, ['onClick']),
504524
...mouseEvents,

components/vc-menu/SubPopupMenu.jsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ const SubPopupMenu = {
116116
expandIcon: PropTypes.any,
117117
overflowedIndicator: PropTypes.any,
118118
children: PropTypes.any.def([]),
119-
forceSubMenuRender: PropTypes.looseBool,
119+
forceSubMenuRender: PropTypes.looseBool.def(true),
120120
},
121121
{
122122
prefixCls: 'rc-menu',

components/vc-menu/commonPropsType.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ export default {
3030
theme: PropTypes.oneOf(['light', 'dark']).def('light'),
3131
getPopupContainer: PropTypes.func,
3232
openTransitionName: PropTypes.string,
33-
forceSubMenuRender: PropTypes.looseBool,
33+
forceSubMenuRender: PropTypes.looseBool.def(true),
3434
selectable: PropTypes.looseBool,
3535
isRootMenu: PropTypes.looseBool.def(true),
3636
builtinPlacements: PropTypes.object.def(() => ({})),

0 commit comments

Comments
 (0)