add menu
parent
94b420dbc3
commit
3af108ffcb
|
@ -8,8 +8,14 @@ export default {
|
||||||
},
|
},
|
||||||
__emit () { // 直接调用listeners,底层组件不需要vueTool记录events
|
__emit () { // 直接调用listeners,底层组件不需要vueTool记录events
|
||||||
const args = [].slice.call(arguments, 0)
|
const args = [].slice.call(arguments, 0)
|
||||||
if (args.length && this.$listeners[args[0]]) {
|
const filterEvent = []
|
||||||
this.$listeners[args[0]](...args.slice(1))
|
const eventName = args[0]
|
||||||
|
if (args.length && this.$listeners[eventName]) {
|
||||||
|
if (filterEvent.includes(eventName)) {
|
||||||
|
this.$emit(eventName, ...args.slice(1))
|
||||||
|
} else {
|
||||||
|
this.$listeners[eventName](...args.slice(1))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,34 +1,9 @@
|
||||||
import clonedeep from 'lodash.clonedeep'
|
import cloneDeep from 'lodash.clonedeep'
|
||||||
// export function cloneVNode (vnode, deep) {
|
|
||||||
// const cloned = new vnode.constructor(
|
|
||||||
// vnode.tag,
|
|
||||||
// clonedeep(vnode.data),
|
|
||||||
// vnode.children,
|
|
||||||
// vnode.text,
|
|
||||||
// vnode.elm,
|
|
||||||
// vnode.context,
|
|
||||||
// clonedeep(vnode.componentOptions),
|
|
||||||
// vnode.asyncFactory
|
|
||||||
// )
|
|
||||||
// cloned.ns = vnode.ns
|
|
||||||
// cloned.isStatic = vnode.isStatic
|
|
||||||
// cloned.key = vnode.key
|
|
||||||
// cloned.isComment = vnode.isComment
|
|
||||||
// cloned.isCloned = true
|
|
||||||
// if (deep && vnode.children) {
|
|
||||||
// cloned.children = cloneVNodes(vnode.children, deep)
|
|
||||||
// }
|
|
||||||
// return cloned
|
|
||||||
// }
|
|
||||||
export function cloneVNode (vnode, deep) {
|
export function cloneVNode (vnode, deep) {
|
||||||
const componentOptions = vnode.componentOptions
|
const componentOptions = vnode.componentOptions
|
||||||
// if (componentOptions) {
|
|
||||||
// componentOptions.propsData = componentOptions.propsData ? clonedeep(componentOptions.propsData) : componentOptions.propsData
|
|
||||||
// }
|
|
||||||
|
|
||||||
const cloned = new vnode.constructor(
|
const cloned = new vnode.constructor(
|
||||||
vnode.tag,
|
vnode.tag,
|
||||||
clonedeep(vnode.data),
|
vnode.data,
|
||||||
vnode.children,
|
vnode.children,
|
||||||
vnode.text,
|
vnode.text,
|
||||||
vnode.elm,
|
vnode.elm,
|
||||||
|
@ -66,21 +41,25 @@ export function cloneVNodes (vnodes, deep) {
|
||||||
|
|
||||||
export function cloneElement (n, nodeProps, clone) {
|
export function cloneElement (n, nodeProps, clone) {
|
||||||
const node = clone ? cloneVNode(n, true) : n
|
const node = clone ? cloneVNode(n, true) : n
|
||||||
const { props = {}, key, on = {}} = nodeProps
|
const { props = {}, key, on = {}, addChildren } = nodeProps
|
||||||
if (node.componentOptions) {
|
|
||||||
node.componentOptions.propsData = node.componentOptions.propsData || {}
|
|
||||||
node.componentOptions.listeners = node.componentOptions.listeners || {}
|
|
||||||
Object.assign(node.componentOptions.propsData, props)
|
|
||||||
Object.assign(node.componentOptions.listeners, on)
|
|
||||||
}
|
|
||||||
|
|
||||||
const data = node.data || {}
|
const data = node.data || {}
|
||||||
const { style = data.style,
|
const { style = data.style,
|
||||||
class: cls = data.class,
|
class: cls = data.class,
|
||||||
attrs = data.attrs,
|
attrs = data.attrs,
|
||||||
ref,
|
ref,
|
||||||
} = nodeProps
|
} = nodeProps
|
||||||
node.data = Object.assign(data, { style, attrs, class: cls, on: { ...(data.on || {}), ...on }})
|
node.data = Object.assign(data, { style, attrs, class: cls })
|
||||||
|
if (node.componentOptions) {
|
||||||
|
node.componentOptions.propsData = node.componentOptions.propsData || {}
|
||||||
|
node.componentOptions.listeners = node.componentOptions.listeners || {}
|
||||||
|
node.componentOptions.propsData = { ...node.componentOptions.propsData, ...props }
|
||||||
|
node.componentOptions.listeners = { ...node.componentOptions.listeners, ...on }
|
||||||
|
addChildren && node.componentOptions.children.push(addChildren)
|
||||||
|
} else {
|
||||||
|
addChildren && (node.children = [...(node.children || []), addChildren])
|
||||||
|
node.data.on = { ...(node.data.on || {}), ...on }
|
||||||
|
}
|
||||||
|
|
||||||
if (key !== undefined) {
|
if (key !== undefined) {
|
||||||
node.key = key
|
node.key = key
|
||||||
node.data.key = key
|
node.data.key = key
|
||||||
|
@ -105,3 +84,17 @@ export function getClass (ele) {
|
||||||
export function getStyle (ele) {
|
export function getStyle (ele) {
|
||||||
return ele.data && (ele.data.style || ele.data.staticStyle)
|
return ele.data && (ele.data.style || ele.data.staticStyle)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function filterEmpty (children = []) {
|
||||||
|
return children.filter(c => c.tag || c.text.trim() !== '')
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getEvents (child) {
|
||||||
|
let events = {}
|
||||||
|
if (child.componentOptions && child.componentOptions.listeners) {
|
||||||
|
events = child.componentOptions.listeners
|
||||||
|
} else if (child.data && child.data.on) {
|
||||||
|
events = child.data.on
|
||||||
|
}
|
||||||
|
return events
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
import { Item, itemProps } from './src/index'
|
import { Item, itemProps } from './src/index'
|
||||||
import { getClass, getStyle } from '../_util/vnode'
|
import { getClass, getStyle } from '../_util/vnode'
|
||||||
import Tooltip from '../tooltip'
|
import Tooltip from '../tooltip'
|
||||||
|
import { getComponentFromProp } from '../_util/props-util'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: itemProps,
|
props: itemProps,
|
||||||
|
@ -14,7 +15,7 @@ export default {
|
||||||
this.$refs.menuItem.onKeyDown(e)
|
this.$refs.menuItem.onKeyDown(e)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
render () {
|
render (h) {
|
||||||
const { inlineCollapsed, $props: props, $slots, $attrs: attrs, $listeners } = this
|
const { inlineCollapsed, $props: props, $slots, $attrs: attrs, $listeners } = this
|
||||||
const itemProps = {
|
const itemProps = {
|
||||||
props,
|
props,
|
||||||
|
|
|
@ -76,7 +76,7 @@ export default {
|
||||||
console.log('onOpenChange', value, this.$refs)
|
console.log('onOpenChange', value, this.$refs)
|
||||||
}
|
}
|
||||||
const commonMenu = () => (
|
const commonMenu = () => (
|
||||||
<Menu onSelect={handleSelect} onOpenChange={onOpenChange}>
|
<Menu onSelect={handleSelect} onOpenChange={onOpenChange} onClick={(e) => console.log('click', e)}>
|
||||||
<SubMenu ref='test' key='1' title={<span>sub menu</span>}>
|
<SubMenu ref='test' key='1' title={<span>sub menu</span>}>
|
||||||
<MenuItem key='1-1'>
|
<MenuItem key='1-1'>
|
||||||
0-1
|
0-1
|
||||||
|
@ -103,7 +103,7 @@ export default {
|
||||||
{commonMenu()}
|
{commonMenu()}
|
||||||
</Clone>
|
</Clone>
|
||||||
</div>
|
</div>
|
||||||
<h3>horizontal and click</h3>
|
{/* <h3>horizontal and click</h3>
|
||||||
<div style={{ margin: '20px', width: '800px' }}>
|
<div style={{ margin: '20px', width: '800px' }}>
|
||||||
<Clone childProps={{
|
<Clone childProps={{
|
||||||
mode: 'horizontal',
|
mode: 'horizontal',
|
||||||
|
@ -131,7 +131,7 @@ export default {
|
||||||
openAnimation: animation,
|
openAnimation: animation,
|
||||||
}} >
|
}} >
|
||||||
{commonMenu()}
|
{commonMenu()}
|
||||||
</Clone></div>
|
</Clone></div>*/}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -43,6 +43,7 @@ export default {
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleClick (e) {
|
handleClick (e) {
|
||||||
|
console.log(e)
|
||||||
this.current = e.key
|
this.current = e.key
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -49,19 +49,19 @@ const Menu = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onDestroy (key) {
|
// onDestroy (key) {
|
||||||
const state = this.$data
|
// const state = this.$data
|
||||||
const sSelectedKeys = state.sSelectedKeys
|
// const sSelectedKeys = state.sSelectedKeys
|
||||||
const sOpenKeys = state.sOpenKeys
|
// const sOpenKeys = state.sOpenKeys
|
||||||
let index = sSelectedKeys.indexOf(key)
|
// let index = sSelectedKeys.indexOf(key)
|
||||||
if (!hasProp(this, 'selectedKeys') && index !== -1) {
|
// if (!hasProp(this, 'selectedKeys') && index !== -1) {
|
||||||
sSelectedKeys.splice(index, 1)
|
// sSelectedKeys.splice(index, 1)
|
||||||
}
|
// }
|
||||||
index = sOpenKeys.indexOf(key)
|
// index = sOpenKeys.indexOf(key)
|
||||||
if (!hasProp(this, 'openKeys') && index !== -1) {
|
// if (!hasProp(this, 'openKeys') && index !== -1) {
|
||||||
sOpenKeys.splice(index, 1)
|
// sOpenKeys.splice(index, 1)
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
|
|
||||||
onSelect (selectInfo) {
|
onSelect (selectInfo) {
|
||||||
const props = this.$props
|
const props = this.$props
|
||||||
|
@ -90,7 +90,7 @@ const Menu = {
|
||||||
this.__emit('click', e)
|
this.__emit('click', e)
|
||||||
},
|
},
|
||||||
|
|
||||||
onOpenChange (e_) {
|
onOpenChange (event) {
|
||||||
const sOpenKeys = this.$data.sOpenKeys.concat()
|
const sOpenKeys = this.$data.sOpenKeys.concat()
|
||||||
let changed = false
|
let changed = false
|
||||||
const processSingle = (e) => {
|
const processSingle = (e) => {
|
||||||
|
@ -109,11 +109,11 @@ const Menu = {
|
||||||
}
|
}
|
||||||
changed = changed || oneChanged
|
changed = changed || oneChanged
|
||||||
}
|
}
|
||||||
if (Array.isArray(e_)) {
|
if (Array.isArray(event)) {
|
||||||
// batch change call
|
// batch change call
|
||||||
e_.forEach(processSingle)
|
event.forEach(processSingle)
|
||||||
} else {
|
} else {
|
||||||
processSingle(e_)
|
processSingle(event)
|
||||||
}
|
}
|
||||||
if (changed) {
|
if (changed) {
|
||||||
if (!hasProp(this, 'openKeys')) {
|
if (!hasProp(this, 'openKeys')) {
|
||||||
|
|
|
@ -15,7 +15,7 @@ const props = {
|
||||||
level: PropTypes.number.def(1),
|
level: PropTypes.number.def(1),
|
||||||
mode: PropTypes.oneOf(['horizontal', 'vertical', 'vertical-left', 'vertical-right', 'inline']).def('vertical'),
|
mode: PropTypes.oneOf(['horizontal', 'vertical', 'vertical-left', 'vertical-right', 'inline']).def('vertical'),
|
||||||
parentMenu: PropTypes.object,
|
parentMenu: PropTypes.object,
|
||||||
clearSubMenuTimers: PropTypes.func.def(noop),
|
// clearSubMenuTimers: PropTypes.func.def(noop),
|
||||||
}
|
}
|
||||||
const MenuItem = {
|
const MenuItem = {
|
||||||
name: 'MenuItem',
|
name: 'MenuItem',
|
||||||
|
@ -30,12 +30,6 @@ const MenuItem = {
|
||||||
this.__emit('destroy', props.eventKey)
|
this.__emit('destroy', props.eventKey)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
__emit () { // 直接调用listeners,底层组件不需要vueTool记录events
|
|
||||||
const args = [].slice.call(arguments, 0)
|
|
||||||
if (args.length && this.$listeners[args[0]]) {
|
|
||||||
this.$listeners[args[0]](...args.slice(1))
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onKeyDown (e) {
|
onKeyDown (e) {
|
||||||
const keyCode = e.keyCode
|
const keyCode = e.keyCode
|
||||||
if (keyCode === KeyCode.ENTER) {
|
if (keyCode === KeyCode.ENTER) {
|
||||||
|
@ -57,10 +51,10 @@ const MenuItem = {
|
||||||
},
|
},
|
||||||
|
|
||||||
onMouseEnter (e) {
|
onMouseEnter (e) {
|
||||||
const { eventKey, parentMenuContext } = this
|
const { eventKey } = this
|
||||||
if (parentMenuContext && parentMenuContext.subMenuInstance) {
|
// if (parentMenuContext && parentMenuContext.subMenuInstance) {
|
||||||
parentMenuContext.subMenuInstance.clearSubMenuTimers()
|
// parentMenuContext.subMenuInstance.clearSubMenuTimers()
|
||||||
}
|
// }
|
||||||
this.__emit('itemHover', {
|
this.__emit('itemHover', {
|
||||||
key: eventKey,
|
key: eventKey,
|
||||||
hover: true,
|
hover: true,
|
||||||
|
@ -80,6 +74,7 @@ const MenuItem = {
|
||||||
item: this,
|
item: this,
|
||||||
domEvent: e,
|
domEvent: e,
|
||||||
}
|
}
|
||||||
|
|
||||||
this.__emit('click', info)
|
this.__emit('click', info)
|
||||||
if (multiple) {
|
if (multiple) {
|
||||||
if (selected) {
|
if (selected) {
|
||||||
|
@ -130,6 +125,7 @@ const MenuItem = {
|
||||||
'aria-disabled': props.disabled,
|
'aria-disabled': props.disabled,
|
||||||
}
|
}
|
||||||
let mouseEvent = {}
|
let mouseEvent = {}
|
||||||
|
|
||||||
if (!props.disabled) {
|
if (!props.disabled) {
|
||||||
mouseEvent = {
|
mouseEvent = {
|
||||||
click: this.onClick,
|
click: this.onClick,
|
||||||
|
|
|
@ -167,16 +167,16 @@ export default {
|
||||||
itemHover: this.onItemHover,
|
itemHover: this.onItemHover,
|
||||||
openChange: this.onOpenChange,
|
openChange: this.onOpenChange,
|
||||||
deselect: this.onDeselect,
|
deselect: this.onDeselect,
|
||||||
destroy: this.onDestroy,
|
// destroy: this.onDestroy,
|
||||||
select: this.onSelect,
|
select: this.onSelect,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if (props.mode === 'inline') {
|
if (props.mode === 'inline') {
|
||||||
newChildProps.props.triggerSubMenuAction = 'click'
|
newChildProps.props.triggerSubMenuAction = 'click'
|
||||||
}
|
}
|
||||||
if (!extraProps.isRootMenu) {
|
// if (!extraProps.isRootMenu) {
|
||||||
newChildProps.props.clearSubMenuTimers = this.clearSubMenuTimers
|
// newChildProps.props.clearSubMenuTimers = this.clearSubMenuTimers
|
||||||
}
|
// }
|
||||||
return cloneElement(child, newChildProps)
|
return cloneElement(child, newChildProps)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ export default {
|
||||||
name: 'SubMenu',
|
name: 'SubMenu',
|
||||||
props: {
|
props: {
|
||||||
mode: PropTypes.oneOf(['horizontal', 'vertical', 'vertical-left', 'vertical-right', 'inline']).def('vertical'),
|
mode: PropTypes.oneOf(['horizontal', 'vertical', 'vertical-left', 'vertical-right', 'inline']).def('vertical'),
|
||||||
title: PropTypes.any.def(''),
|
title: PropTypes.any,
|
||||||
selectedKeys: PropTypes.array.def([]),
|
selectedKeys: PropTypes.array.def([]),
|
||||||
openKeys: PropTypes.array.def([]),
|
openKeys: PropTypes.array.def([]),
|
||||||
openChange: PropTypes.func.def(noop),
|
openChange: PropTypes.func.def(noop),
|
||||||
|
@ -42,6 +42,7 @@ export default {
|
||||||
subMenuCloseDelay: PropTypes.number.def(0.1),
|
subMenuCloseDelay: PropTypes.number.def(0.1),
|
||||||
level: PropTypes.number.def(1),
|
level: PropTypes.number.def(1),
|
||||||
inlineIndent: PropTypes.number.def(24),
|
inlineIndent: PropTypes.number.def(24),
|
||||||
|
openTransitionName: PropTypes.string,
|
||||||
},
|
},
|
||||||
inject: {
|
inject: {
|
||||||
parentMenuContext: { default: undefined },
|
parentMenuContext: { default: undefined },
|
||||||
|
@ -63,10 +64,16 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeDestroy () {
|
beforeDestroy () {
|
||||||
const { eventKey, parentMenuContext } = this
|
const { eventKey } = this
|
||||||
this.__emit('destroy', eventKey)
|
this.__emit('destroy', eventKey)
|
||||||
if (parentMenuContext.subMenuInstance === this) {
|
// if (parentMenuContext.subMenuInstance === this) {
|
||||||
this.clearSubMenuTimers()
|
// this.clearSubMenuTimers()
|
||||||
|
// }
|
||||||
|
if (this.minWidthTimeout) {
|
||||||
|
clearTimeout(this.minWidthTimeout)
|
||||||
|
}
|
||||||
|
if (this.mouseenterTimeout) {
|
||||||
|
clearTimeout(this.mouseenterTimeout)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -75,15 +82,16 @@ export default {
|
||||||
if (mode !== 'horizontal' || !isRootMenu || !this.isOpen()) {
|
if (mode !== 'horizontal' || !isRootMenu || !this.isOpen()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
setTimeout(() => {
|
const self = this
|
||||||
if (!this.subMenuTitle || !this.menuInstance) {
|
this.minWidthTimeout = setTimeout(() => {
|
||||||
|
if (!self.$refs.subMenuTitle || !self.$refs.menuInstance) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
const popupMenu = this.$refs.menuInstance.$el
|
const popupMenu = self.$refs.menuInstance.$el
|
||||||
if (popupMenu.offsetWidth >= this.subMenuTitle.offsetWidth) {
|
if (popupMenu.offsetWidth >= self.$refs.subMenuTitle.offsetWidth) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
popupMenu.style.minWidth = `${this.subMenuTitle.offsetWidth}px`
|
popupMenu.style.minWidth = `${self.$refs.subMenuTitle.offsetWidth}px`
|
||||||
}, 0)
|
}, 0)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -136,7 +144,7 @@ export default {
|
||||||
|
|
||||||
onMouseEnter (e) {
|
onMouseEnter (e) {
|
||||||
const { eventKey: key } = this.$props
|
const { eventKey: key } = this.$props
|
||||||
this.clearSubMenuLeaveTimer()
|
// this.clearSubMenuLeaveTimer()
|
||||||
this.setState({
|
this.setState({
|
||||||
defaultActiveFirst: false,
|
defaultActiveFirst: false,
|
||||||
})
|
})
|
||||||
|
@ -152,20 +160,24 @@ export default {
|
||||||
parentMenuContext,
|
parentMenuContext,
|
||||||
} = this
|
} = this
|
||||||
parentMenuContext.subMenuInstance = this
|
parentMenuContext.subMenuInstance = this
|
||||||
parentMenuContext.subMenuLeaveFn = () => {
|
// parentMenuContext.subMenuLeaveFn = () => {
|
||||||
// trigger mouseleave
|
// // trigger mouseleave
|
||||||
this.__emit('mouseleave', {
|
// this.__emit('mouseleave', {
|
||||||
key: eventKey,
|
// key: eventKey,
|
||||||
domEvent: e,
|
// domEvent: e,
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
this.__emit('mouseleave', {
|
||||||
|
key: eventKey,
|
||||||
|
domEvent: e,
|
||||||
|
})
|
||||||
// prevent popup menu and submenu gap
|
// prevent popup menu and submenu gap
|
||||||
parentMenuContext.subMenuLeaveTimer = setTimeout(parentMenuContext.subMenuLeaveFn, 100)
|
// parentMenuContext.subMenuLeaveTimer = setTimeout(parentMenuContext.subMenuLeaveFn, 100)
|
||||||
},
|
},
|
||||||
|
|
||||||
onTitleMouseEnter (domEvent) {
|
onTitleMouseEnter (domEvent) {
|
||||||
const { eventKey: key } = this.$props
|
const { eventKey: key } = this.$props
|
||||||
this.clearSubMenuTitleLeaveTimer()
|
// this.clearSubMenuTitleLeaveTimer()
|
||||||
this.__emit('itemHover', {
|
this.__emit('itemHover', {
|
||||||
key,
|
key,
|
||||||
hover: true,
|
hover: true,
|
||||||
|
@ -179,17 +191,25 @@ export default {
|
||||||
onTitleMouseLeave (e) {
|
onTitleMouseLeave (e) {
|
||||||
const { eventKey, parentMenuContext } = this
|
const { eventKey, parentMenuContext } = this
|
||||||
parentMenuContext.subMenuInstance = this
|
parentMenuContext.subMenuInstance = this
|
||||||
parentMenuContext.subMenuTitleLeaveFn = () => {
|
this.__emit('itemHover', {
|
||||||
this.__emit('itemHover', {
|
key: eventKey,
|
||||||
key: eventKey,
|
hover: false,
|
||||||
hover: false,
|
})
|
||||||
})
|
this.__emit('titleMouseleave', {
|
||||||
this.__emit('titleMouseleave', {
|
key: eventKey,
|
||||||
key: eventKey,
|
domEvent: e,
|
||||||
domEvent: e,
|
})
|
||||||
})
|
// parentMenuContext.subMenuTitleLeaveFn = () => {
|
||||||
}
|
// this.__emit('itemHover', {
|
||||||
parentMenuContext.subMenuTitleLeaveTimer = setTimeout(parentMenuContext.subMenuTitleLeaveFn, 100)
|
// key: eventKey,
|
||||||
|
// hover: false,
|
||||||
|
// })
|
||||||
|
// this.__emit('titleMouseleave', {
|
||||||
|
// key: eventKey,
|
||||||
|
// domEvent: e,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// parentMenuContext.subMenuTitleLeaveTimer = setTimeout(parentMenuContext.subMenuTitleLeaveFn, 100)
|
||||||
},
|
},
|
||||||
|
|
||||||
onTitleClick (e) {
|
onTitleClick (e) {
|
||||||
|
@ -239,38 +259,57 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// triggerOpenChange (open, type) {
|
||||||
|
// const key = this.$props.eventKey
|
||||||
|
// this.__emit('openChange', {
|
||||||
|
// key,
|
||||||
|
// item: this,
|
||||||
|
// trigger: type,
|
||||||
|
// open,
|
||||||
|
// })
|
||||||
|
// },
|
||||||
triggerOpenChange (open, type) {
|
triggerOpenChange (open, type) {
|
||||||
const key = this.$props.eventKey
|
const key = this.$props.eventKey
|
||||||
this.__emit('openChange', {
|
const openChange = () => {
|
||||||
key,
|
this.__emit('openChange', {
|
||||||
item: this,
|
key,
|
||||||
trigger: type,
|
item: this,
|
||||||
open,
|
trigger: type,
|
||||||
})
|
open,
|
||||||
},
|
})
|
||||||
|
}
|
||||||
clearSubMenuTimers () {
|
if (type === 'mouseenter') {
|
||||||
this.clearSubMenuLeaveTimer()
|
// make sure mouseenter happen after other menu item's mouseleave
|
||||||
this.clearSubMenuTitleLeaveTimer()
|
this.mouseenterTimeout = setTimeout(() => {
|
||||||
},
|
openChange()
|
||||||
|
}, 0)
|
||||||
clearSubMenuTitleLeaveTimer () {
|
} else {
|
||||||
const parentMenuContext = this.parentMenuContext
|
openChange()
|
||||||
if (parentMenuContext.subMenuTitleLeaveTimer) {
|
|
||||||
clearTimeout(parentMenuContext.subMenuTitleLeaveTimer)
|
|
||||||
parentMenuContext.subMenuTitleLeaveTimer = null
|
|
||||||
parentMenuContext.subMenuTitleLeaveFn = null
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
clearSubMenuLeaveTimer () {
|
// clearSubMenuTimers () {
|
||||||
const parentMenuContext = this.parentMenuContext
|
// this.clearSubMenuLeaveTimer()
|
||||||
if (parentMenuContext.subMenuLeaveTimer) {
|
// this.clearSubMenuTitleLeaveTimer()
|
||||||
clearTimeout(parentMenuContext.subMenuLeaveTimer)
|
// },
|
||||||
parentMenuContext.subMenuLeaveTimer = null
|
|
||||||
parentMenuContext.subMenuLeaveFn = null
|
// clearSubMenuTitleLeaveTimer () {
|
||||||
}
|
// const parentMenuContext = this.parentMenuContext
|
||||||
},
|
// if (parentMenuContext.subMenuTitleLeaveTimer) {
|
||||||
|
// clearTimeout(parentMenuContext.subMenuTitleLeaveTimer)
|
||||||
|
// parentMenuContext.subMenuTitleLeaveTimer = null
|
||||||
|
// parentMenuContext.subMenuTitleLeaveFn = null
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
|
||||||
|
// clearSubMenuLeaveTimer () {
|
||||||
|
// const parentMenuContext = this.parentMenuContext
|
||||||
|
// if (parentMenuContext.subMenuLeaveTimer) {
|
||||||
|
// clearTimeout(parentMenuContext.subMenuLeaveTimer)
|
||||||
|
// parentMenuContext.subMenuLeaveTimer = null
|
||||||
|
// parentMenuContext.subMenuLeaveFn = null
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
|
||||||
isChildrenSelected () {
|
isChildrenSelected () {
|
||||||
const ret = { find: false }
|
const ret = { find: false }
|
||||||
|
@ -284,7 +323,7 @@ export default {
|
||||||
renderChildren (children, vShow) {
|
renderChildren (children, vShow) {
|
||||||
const props = this.$props
|
const props = this.$props
|
||||||
const isOpen = this.isOpen()
|
const isOpen = this.isOpen()
|
||||||
const { select, deselect, destroy, openChange } = this.$listeners
|
const { select, deselect, openChange } = this.$listeners
|
||||||
const subPopupMenuProps = {
|
const subPopupMenuProps = {
|
||||||
props: {
|
props: {
|
||||||
mode: props.mode === 'horizontal' ? 'vertical' : props.mode,
|
mode: props.mode === 'horizontal' ? 'vertical' : props.mode,
|
||||||
|
@ -304,11 +343,11 @@ export default {
|
||||||
defaultActiveFirst: this.$data.defaultActiveFirst,
|
defaultActiveFirst: this.$data.defaultActiveFirst,
|
||||||
multiple: props.multiple,
|
multiple: props.multiple,
|
||||||
prefixCls: props.rootPrefixCls,
|
prefixCls: props.rootPrefixCls,
|
||||||
clearSubMenuTimers: this.clearSubMenuTimers,
|
// clearSubMenuTimers: this.clearSubMenuTimers,
|
||||||
},
|
},
|
||||||
on: {
|
on: {
|
||||||
click: this.onSubMenuClick,
|
click: this.onSubMenuClick,
|
||||||
select, deselect, destroy, openChange,
|
select, deselect, openChange,
|
||||||
},
|
},
|
||||||
id: this._menuId,
|
id: this._menuId,
|
||||||
ref: 'menuInstance',
|
ref: 'menuInstance',
|
||||||
|
@ -448,7 +487,7 @@ export default {
|
||||||
onPopupVisibleChange={this.onPopupVisibleChange}
|
onPopupVisibleChange={this.onPopupVisibleChange}
|
||||||
forceRender={props.forceSubMenuRender}
|
forceRender={props.forceSubMenuRender}
|
||||||
// popupTransitionName='rc-menu-open-slide-up'
|
// popupTransitionName='rc-menu-open-slide-up'
|
||||||
popupAnimation={animProps}
|
popupAnimation={transitionProps}
|
||||||
>
|
>
|
||||||
<template slot='popup'>
|
<template slot='popup'>
|
||||||
{this.haveOpened ? children : null}
|
{this.haveOpened ? children : null}
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { noop } from './util'
|
||||||
export default {
|
export default {
|
||||||
name: 'SubPopupMenu',
|
name: 'SubPopupMenu',
|
||||||
props: { ...commonPropsType,
|
props: { ...commonPropsType,
|
||||||
clearSubMenuTimers: PropTypes.func.def(noop),
|
// clearSubMenuTimers: PropTypes.func.def(noop),
|
||||||
},
|
},
|
||||||
|
|
||||||
mixins: [MenuMixin, BaseMixin],
|
mixins: [MenuMixin, BaseMixin],
|
||||||
|
|
|
@ -88,8 +88,13 @@ export default {
|
||||||
getTransitionName () {
|
getTransitionName () {
|
||||||
const props = this.$props
|
const props = this.$props
|
||||||
let transitionName = props.transitionName
|
let transitionName = props.transitionName
|
||||||
if (!transitionName && typeof props.animation === 'string') {
|
const animation = props.animation
|
||||||
transitionName = `${props.animation}`
|
if (!transitionName) {
|
||||||
|
if (typeof animation === 'string') {
|
||||||
|
transitionName = `${animation}`
|
||||||
|
} else if (animation.props && animation.props.name) {
|
||||||
|
transitionName = animation.props.name
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return transitionName
|
return transitionName
|
||||||
},
|
},
|
||||||
|
@ -152,9 +157,9 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof animation === 'object') {
|
if (typeof animation === 'object') {
|
||||||
const { on = {}, ...otherProps } = animation
|
const { on = {}, props = {}} = animation
|
||||||
transitionProps.props = { ...transitionProps.props, ...otherProps }
|
transitionProps.props = { ...transitionProps.props, ...props }
|
||||||
transitionProps.on = { ...on, afterLeave: (el) => {
|
transitionProps.on = { ...transitionEvent, ...on, afterLeave: (el) => {
|
||||||
transitionEvent.afterLeave(el)
|
transitionEvent.afterLeave(el)
|
||||||
on.afterLeave && on.afterLeave(el)
|
on.afterLeave && on.afterLeave(el)
|
||||||
} }
|
} }
|
||||||
|
|
|
@ -7,7 +7,7 @@ import warning from '../_util/warning'
|
||||||
import Popup from './Popup'
|
import Popup from './Popup'
|
||||||
import { getAlignFromPlacement, getPopupClassNameFromAlign, noop } from './utils'
|
import { getAlignFromPlacement, getPopupClassNameFromAlign, noop } from './utils'
|
||||||
import BaseMixin from '../_util/BaseMixin'
|
import BaseMixin from '../_util/BaseMixin'
|
||||||
import { cloneElement, cloneVNode } from '../_util/vnode'
|
import { cloneElement, filterEmpty, getEvents } from '../_util/vnode'
|
||||||
|
|
||||||
function returnEmptyString () {
|
function returnEmptyString () {
|
||||||
return ''
|
return ''
|
||||||
|
@ -79,8 +79,8 @@ export default {
|
||||||
beforeCreate () {
|
beforeCreate () {
|
||||||
ALL_HANDLERS.forEach((h) => {
|
ALL_HANDLERS.forEach((h) => {
|
||||||
this[`fire${h}`] = (e) => {
|
this[`fire${h}`] = (e) => {
|
||||||
const ev = `on${h[0].toUpperCase() + h.slice(1)}`
|
// const ev = `on${h[0].toUpperCase() + h.slice(1)}`
|
||||||
this.fireEvents(ev, e)
|
this.fireEvents(h, e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
@ -258,7 +258,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
getRootDomNode () {
|
getRootDomNode () {
|
||||||
return this.$el.children ? this.$el.children[0] : this.$el
|
return this.$el
|
||||||
},
|
},
|
||||||
|
|
||||||
handleGetPopupClassFromAlign (align) {
|
handleGetPopupClassFromAlign (align) {
|
||||||
|
@ -401,18 +401,14 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
createTwoChains (event) {
|
createTwoChains (event, child) {
|
||||||
const child = this.$slots.default[0]
|
|
||||||
let fn = () => {
|
let fn = () => {
|
||||||
}
|
}
|
||||||
child.data = child.data || {}
|
const events = this.$listeners
|
||||||
child.data.on = child.data.on || {}
|
if (this.childOriginEvents[event] && events[event]) {
|
||||||
const childEvents = child.data.on
|
|
||||||
const events = (this.data ? this.data.on : {}) || {}
|
|
||||||
if (childEvents[event] && events[event]) {
|
|
||||||
return this[`fire${event}`]
|
return this[`fire${event}`]
|
||||||
}
|
}
|
||||||
fn = childEvents[event] || events[event] || fn
|
fn = this.childOriginEvents[event] || events[event] || fn
|
||||||
return fn
|
return fn
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -456,13 +452,10 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fireEvents (type, e) {
|
fireEvents (type, e) {
|
||||||
const child = this.$slots.default[0]
|
if (this.childOriginEvents[type]) {
|
||||||
if (child && child.data && child.data.on && child.data.on[type]) {
|
this.childOriginEvents[type](e)
|
||||||
child.data.on[type](e)
|
|
||||||
}
|
|
||||||
if (this.data && this.data.on && this.data.on[type]) {
|
|
||||||
this.data.on[type](e)
|
|
||||||
}
|
}
|
||||||
|
this.__emit(type, e)
|
||||||
},
|
},
|
||||||
|
|
||||||
close () {
|
close () {
|
||||||
|
@ -470,11 +463,12 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
render (h) {
|
render (h) {
|
||||||
const children = this.$slots.default
|
const children = filterEmpty(this.$slots.default)
|
||||||
if (children.length > 1) {
|
if (children.length > 1) {
|
||||||
warning(false, 'Trigger $slots.default.length > 1, just support only one default', true)
|
warning(false, 'Trigger $slots.default.length > 1, just support only one default', true)
|
||||||
}
|
}
|
||||||
const child = children[0]
|
const child = children[0]
|
||||||
|
this.childOriginEvents = getEvents(child)
|
||||||
const newChildProps = {
|
const newChildProps = {
|
||||||
props: {},
|
props: {},
|
||||||
on: {},
|
on: {},
|
||||||
|
@ -484,7 +478,7 @@ export default {
|
||||||
if (this.isContextMenuToShow()) {
|
if (this.isContextMenuToShow()) {
|
||||||
newChildProps.on.contextMenu = this.onContextMenu
|
newChildProps.on.contextMenu = this.onContextMenu
|
||||||
} else {
|
} else {
|
||||||
newChildProps.on.contextMenu = this.createTwoChains('contextMenu')
|
newChildProps.on.contextMenu = this.createTwoChains('contextMenu', child)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isClickToHide() || this.isClickToShow()) {
|
if (this.isClickToHide() || this.isClickToShow()) {
|
||||||
|
@ -492,42 +486,44 @@ export default {
|
||||||
newChildProps.on.mousedown = this.onMousedown
|
newChildProps.on.mousedown = this.onMousedown
|
||||||
// newChildProps.on.touchStart = this.onTouchStart
|
// newChildProps.on.touchStart = this.onTouchStart
|
||||||
} else {
|
} else {
|
||||||
newChildProps.on.click = this.createTwoChains('click')
|
newChildProps.on.click = this.createTwoChains('click', child)
|
||||||
newChildProps.on.mousedown = this.createTwoChains('mousedown')
|
newChildProps.on.mousedown = this.createTwoChains('mousedown', child)
|
||||||
// newChildProps.on.TouchStart = this.createTwoChains('onTouchStart')
|
// newChildProps.on.TouchStart = this.createTwoChains('onTouchStart', child)
|
||||||
}
|
}
|
||||||
if (this.isMouseEnterToShow()) {
|
if (this.isMouseEnterToShow()) {
|
||||||
newChildProps.on.mouseenter = this.onMouseenter
|
newChildProps.on.mouseenter = this.onMouseenter
|
||||||
} else {
|
} else {
|
||||||
newChildProps.on.mouseenter = this.createTwoChains('mouseenter')
|
newChildProps.on.mouseenter = this.createTwoChains('mouseenter', child)
|
||||||
}
|
}
|
||||||
if (this.isMouseLeaveToHide()) {
|
if (this.isMouseLeaveToHide()) {
|
||||||
newChildProps.on.mouseleave = this.onMouseleave
|
newChildProps.on.mouseleave = this.onMouseleave
|
||||||
} else {
|
} else {
|
||||||
newChildProps.on.mouseleave = this.createTwoChains('mouseleave')
|
newChildProps.on.mouseleave = this.createTwoChains('mouseleave', child)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.isFocusToShow() || this.isBlurToHide()) {
|
if (this.isFocusToShow() || this.isBlurToHide()) {
|
||||||
newChildProps.on.focus = this.onFocus
|
newChildProps.on.focus = this.onFocus
|
||||||
newChildProps.on.blur = this.onBlur
|
newChildProps.on.blur = this.onBlur
|
||||||
} else {
|
} else {
|
||||||
newChildProps.on.focus = this.createTwoChains('focus')
|
newChildProps.on.focus = this.createTwoChains('focus', child)
|
||||||
newChildProps.on.blur = this.createTwoChains('blur')
|
newChildProps.on.blur = this.createTwoChains('blur', child)
|
||||||
}
|
}
|
||||||
|
|
||||||
const trigger = cloneElement(cloneVNode(child), newChildProps)
|
|
||||||
const { sPopupVisible, forceRender } = this
|
const { sPopupVisible, forceRender } = this
|
||||||
if (sPopupVisible || forceRender || this._component) {
|
if (sPopupVisible || forceRender || this._component) {
|
||||||
this._component = this.getComponent(h)
|
this._component = this.getComponent(h)
|
||||||
} else {
|
} else {
|
||||||
this._component = null
|
this._component = null
|
||||||
}
|
}
|
||||||
return (
|
newChildProps.addChildren = this._component
|
||||||
<span>
|
// // 复制一份事件,防止cloneElement
|
||||||
{trigger}
|
// if (child.componentOptions && child.componentOptions.listeners) {
|
||||||
{this._component}
|
// console.log(child.componentOptions.listeners)
|
||||||
</span>
|
// child.componentOptions.listeners = { ...child.componentOptions.listeners }
|
||||||
)
|
// } else if (child.data && child.data.on) {
|
||||||
|
// child.data.on = { ...child.data.on }
|
||||||
|
// }
|
||||||
|
const trigger = cloneElement(child, newChildProps)
|
||||||
|
return trigger
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue