From 5c425cec90e408bf901edcaff6d2466a8c7fbd70 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Thu, 18 Jun 2020 00:19:14 +0800 Subject: [PATCH] fix: menu --- components/_util/props-util.js | 15 +++++++++------ components/_util/proxyComponent.jsx | 8 +++----- components/_util/store/connect.jsx | 3 +-- components/_util/util.js | 6 +++--- components/menu/MenuItem.jsx | 4 ++-- components/vc-menu/DOMWrap.jsx | 8 +++++--- components/vc-menu/MenuItem.jsx | 5 ++--- components/vc-menu/SubPopupMenu.jsx | 12 +++++++++--- components/vc-menu/commonPropsType.js | 1 - components/vc-menu/util.js | 4 ++++ 10 files changed, 38 insertions(+), 28 deletions(-) diff --git a/components/_util/props-util.js b/components/_util/props-util.js index 85ac8b81f..df189719c 100644 --- a/components/_util/props-util.js +++ b/components/_util/props-util.js @@ -69,8 +69,8 @@ const getSlots = ele => { }; const getSlot = (self, name = 'default', options = {}) => { let res = self.$slots[name] && self.$slots[name](options); - while (res && res.length === 1 && res[0].type === Fragment) { - res = res[0].children; + while (res && res.length === 1 && (res[0].type === Fragment || Array.isArray(res[0]))) { + res = res[0].children || res[0]; } return res; }; @@ -105,12 +105,15 @@ const getOptionProps = instance => { } }); } else if (isVNode(instance) && typeof instance.type === 'object') { - const props = instance.props || {}; + const originProps = instance.props || {}; + const props = {}; + Object.keys(originProps).forEach(key => { + props[camelize(key)] = originProps[key]; + }); const options = instance.type.props; Object.keys(options).forEach(k => { - const hyphenateKey = hyphenate(k); - const v = resolvePropValue(options, props, k, props[hyphenateKey], hyphenateKey); - if (v !== undefined || hyphenateKey in props) { + const v = resolvePropValue(options, props, k, props[k]); + if (v !== undefined || k in props) { res[k] = v; } }); diff --git a/components/_util/proxyComponent.jsx b/components/_util/proxyComponent.jsx index 3adb4db2d..e93a301a6 100644 --- a/components/_util/proxyComponent.jsx +++ b/components/_util/proxyComponent.jsx @@ -17,7 +17,6 @@ export default function wrapWithConnect(WrappedComponent) { const ProxyWrappedComponent = { props, inheritAttrs: false, - model: WrappedComponent.model, name: `Proxy_${getDisplayName(WrappedComponent)}`, methods: { getProxyWrappedInstance() { @@ -25,17 +24,16 @@ export default function wrapWithConnect(WrappedComponent) { }, }, render() { - const { $slots = {} } = this; + const { $slots = {}, $attrs } = this; const props = getOptionProps(this); const wrapProps = { ...props, + ...$attrs, __propsSymbol__: Symbol(), componentWillReceiveProps: { ...props }, - children: props.children || $slots?.default() || [], - slots: $slots, ref: 'wrappedInstance', }; - return createVNode(WrappedComponent, wrapProps); + return createVNode(WrappedComponent, wrapProps, $slots); // return ( // // diff --git a/components/_util/store/connect.jsx b/components/_util/store/connect.jsx index 0891d6daa..104612398 100644 --- a/components/_util/store/connect.jsx +++ b/components/_util/store/connect.jsx @@ -92,10 +92,9 @@ export default function connect(mapStateToProps) { ...subscribed, ...$attrs, store, - slots: $slots, ref: 'wrappedInstance', }; - return createVNode(WrappedComponent, wrapProps); + return createVNode(WrappedComponent, wrapProps, $slots); // return ; }, }; diff --git a/components/_util/util.js b/components/_util/util.js index a1c309ebd..18252b386 100644 --- a/components/_util/util.js +++ b/components/_util/util.js @@ -27,7 +27,7 @@ const hasOwnProperty = Object.prototype.hasOwnProperty; const hasOwn = (val, key) => hasOwnProperty.call(val, key); // change from vue sourcecode -function resolvePropValue(options, props, key, value, hyphenateKey) { +function resolvePropValue(options, props, key, value) { const opt = options[key]; if (opt != null) { const hasDefault = hasOwn(opt, 'default'); @@ -38,9 +38,9 @@ function resolvePropValue(options, props, key, value, hyphenateKey) { } // boolean casting if (opt[0 /* shouldCast */]) { - if (!hasOwn(props, hyphenateKey) && !hasDefault) { + if (!hasOwn(props, key) && !hasDefault) { value = false; - } else if (opt[1 /* shouldCastTrue */] && (value === '' || value === hyphenateKey)) { + } else if (opt[1 /* shouldCastTrue */] && (value === '' || value === hyphenate(key))) { value = true; } } diff --git a/components/menu/MenuItem.jsx b/components/menu/MenuItem.jsx index 63148cde0..3ae132224 100644 --- a/components/menu/MenuItem.jsx +++ b/components/menu/MenuItem.jsx @@ -23,10 +23,10 @@ export default { render() { const props = getOptionProps(this); const { level, title, rootPrefixCls } = props; - const { getInlineCollapsed, $slots, $attrs: attrs } = this; + const { getInlineCollapsed, $attrs: attrs } = this; const inlineCollapsed = getInlineCollapsed(); const tooltipProps = { - title: title || (level === 1 ? $slots.default : ''), + title: title || (level === 1 ? getSlot(this) : ''), }; const siderCollapsed = this.layoutSiderContext.sCollapsed; if (!siderCollapsed && !inlineCollapsed) { diff --git a/components/vc-menu/DOMWrap.jsx b/components/vc-menu/DOMWrap.jsx index 651a09129..10fe551c9 100644 --- a/components/vc-menu/DOMWrap.jsx +++ b/components/vc-menu/DOMWrap.jsx @@ -4,7 +4,7 @@ import SubMenu from './SubMenu'; import BaseMixin from '../_util/BaseMixin'; import { getWidth, setStyle, menuAllProps } from './util'; import { cloneElement } from '../_util/vnode'; -import { getPropsData, getSlot, getAllProps } from '../_util/props-util'; +import { getPropsData, getAllProps, getSlot } from '../_util/props-util'; const canUseDOM = !!( typeof window !== 'undefined' && @@ -241,7 +241,10 @@ const DOMWrap = { const eventKey = getPropsData(childNode).eventKey; if (this.mode === 'horizontal') { let overflowed = this.getOverflowedSubMenuItem(eventKey, []); - if (lastVisibleIndex !== undefined && className[`${this.prefixCls}-root`] !== -1) { + if ( + lastVisibleIndex !== undefined && + className.indexOf(`${this.prefixCls}-root`) !== -1 + ) { if (index > lastVisibleIndex) { item = cloneElement( childNode, @@ -299,7 +302,6 @@ DOMWrap.props = { visible: PropTypes.bool, hiddenClassName: PropTypes.string, tag: PropTypes.string.def('div'), - children: PropTypes.any, }; export default DOMWrap; diff --git a/components/vc-menu/MenuItem.jsx b/components/vc-menu/MenuItem.jsx index 9910bbb5d..9b8836a13 100644 --- a/components/vc-menu/MenuItem.jsx +++ b/components/vc-menu/MenuItem.jsx @@ -183,14 +183,13 @@ const MenuItem = { if (props.mode === 'inline') { style.paddingLeft = `${props.inlineIndent * props.level}px`; } - [...menuAllProps, 'children', 'slots', '__propsSymbol__', 'componentWillReceiveProps'].forEach( - key => delete props[key], - ); + menuAllProps.forEach(key => delete props[key]); const liProps = { ...props, ...attrs, ...mouseEvent, }; + delete liProps.children; return (
  • {getSlot(this)} diff --git a/components/vc-menu/SubPopupMenu.jsx b/components/vc-menu/SubPopupMenu.jsx index 5c83a664e..42986ac4b 100644 --- a/components/vc-menu/SubPopupMenu.jsx +++ b/components/vc-menu/SubPopupMenu.jsx @@ -274,7 +274,7 @@ const SubPopupMenu = { const state = this.$props.store.getState(); const props = this.$props; const key = getKeyFromChildrenIndex(child, props.eventKey, i); - const childProps = { ...getOptionProps(child), ...child.props }; // child.props 包含事件 + const childProps = child.props; // 不包含默认值 const isActive = key === state.activeKey[getEventKey(this.$props)]; if (!childProps.disabled) { @@ -337,11 +337,15 @@ const SubPopupMenu = { }, render() { const props = { ...this.$props }; - const { onEvents } = splitAttrs(this.$attrs); + const { onEvents, extraAttrs } = splitAttrs(this.$attrs); const { eventKey, prefixCls, visible, level, mode, theme } = props; this.instanceArray = []; this.instanceArrayKeyIndexMap = {}; - const className = classNames(props.class, props.prefixCls, `${props.prefixCls}-${props.mode}`); + const className = classNames( + extraAttrs.class, + props.prefixCls, + `${props.prefixCls}-${props.mode}`, + ); menuAllProps.forEach(key => delete props[key]); // Otherwise, the propagated click event will trigger another onClick delete onEvents.onClick; @@ -357,6 +361,7 @@ const SubPopupMenu = { overflowedIndicator: getComponent(this, 'overflowedIndicator'), role: props.role || 'menu', class: className, + style: extraAttrs.style, ...onEvents, }; // if (props.id) { @@ -366,6 +371,7 @@ const SubPopupMenu = { domWrapProps.tabIndex = '0'; domWrapProps.onKeydown = this.onKeyDown; } + delete domWrapProps.children; return ( // ESLint is not smart enough to know that the type of `children` was checked. /* eslint-disable */ diff --git a/components/vc-menu/commonPropsType.js b/components/vc-menu/commonPropsType.js index d2a97a1e0..f7bab2c2b 100644 --- a/components/vc-menu/commonPropsType.js +++ b/components/vc-menu/commonPropsType.js @@ -37,5 +37,4 @@ export default { itemIcon: PropTypes.any, expandIcon: PropTypes.any, overflowedIndicator: PropTypes.any, - children: PropTypes.any, }; diff --git a/components/vc-menu/util.js b/components/vc-menu/util.js index 1b60c91ca..7e653ea18 100644 --- a/components/vc-menu/util.js +++ b/components/vc-menu/util.js @@ -110,6 +110,10 @@ export const menuAllProps = [ 'onTitleMouseleave', 'onTitleClick', '__propsSymbol__', + 'slots', + 'ref', + 'componentWillReceiveProps', + 'isRootMenu', ]; // ref: https://github.com/ant-design/ant-design/issues/14007