2017-12-12 13:49:02 +08:00
|
|
|
<script>
|
2017-12-27 18:15:11 +08:00
|
|
|
import PropTypes from '../../_util/vue-types'
|
2017-12-12 13:49:02 +08:00
|
|
|
import MenuMixin from './MenuMixin'
|
|
|
|
import StateMixin from '../../_util/StateMixin'
|
2018-01-02 19:05:02 +08:00
|
|
|
import hasProp from '../../_util/hasProp'
|
2018-01-04 19:06:54 +08:00
|
|
|
import commonPropsType from './commonPropsType'
|
2017-12-12 13:49:02 +08:00
|
|
|
|
|
|
|
const Menu = {
|
|
|
|
name: 'Menu',
|
|
|
|
props: {
|
|
|
|
getPopupContainer: PropTypes.func,
|
|
|
|
openTransitionName: PropTypes.string,
|
|
|
|
forceSubMenuRender: PropTypes.bool,
|
|
|
|
selectable: PropTypes.bool.def(true),
|
2018-01-04 19:06:54 +08:00
|
|
|
...commonPropsType,
|
2017-12-12 13:49:02 +08:00
|
|
|
},
|
|
|
|
mixins: [StateMixin, MenuMixin],
|
|
|
|
|
|
|
|
data () {
|
|
|
|
const props = this.$props
|
2018-01-02 19:05:02 +08:00
|
|
|
let sSelectedKeys = props.defaultSelectedKeys
|
|
|
|
let sOpenKeys = props.defaultOpenKeys
|
2018-01-08 18:31:04 +08:00
|
|
|
if (hasProp(this, 'selectedKeys')) {
|
|
|
|
sSelectedKeys = props.selectedKeys || []
|
|
|
|
}
|
|
|
|
if (hasProp(this, 'openKeys')) {
|
|
|
|
sOpenKeys = props.openKeys || []
|
|
|
|
}
|
|
|
|
|
2017-12-29 18:45:11 +08:00
|
|
|
this.isRootMenu = true
|
2017-12-12 13:49:02 +08:00
|
|
|
return {
|
2018-01-02 19:05:02 +08:00
|
|
|
sSelectedKeys,
|
|
|
|
sOpenKeys,
|
2017-12-12 13:49:02 +08:00
|
|
|
}
|
|
|
|
},
|
2017-12-27 18:15:11 +08:00
|
|
|
watch: {
|
|
|
|
'$props': {
|
|
|
|
handler: function (nextProps) {
|
|
|
|
const props = {}
|
2018-01-08 18:31:04 +08:00
|
|
|
if (hasProp(this, 'selectedKeys')) {
|
2018-01-02 19:05:02 +08:00
|
|
|
props.sSelectedKeys = nextProps.selectedKeys || []
|
2017-12-27 18:15:11 +08:00
|
|
|
}
|
2018-01-08 18:31:04 +08:00
|
|
|
if (hasProp(this, 'selectedKeys')) {
|
2018-01-02 19:05:02 +08:00
|
|
|
props.sOpenKeys = nextProps.openKeys || []
|
2017-12-27 18:15:11 +08:00
|
|
|
}
|
|
|
|
this.setState(props)
|
|
|
|
},
|
|
|
|
deep: true,
|
|
|
|
},
|
2017-12-12 13:49:02 +08:00
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
onDestroy (key) {
|
|
|
|
const state = this.$data
|
2018-01-02 19:05:02 +08:00
|
|
|
const sSelectedKeys = state.sSelectedKeys
|
|
|
|
const sOpenKeys = state.sOpenKeys
|
|
|
|
let index = sSelectedKeys.indexOf(key)
|
|
|
|
if (!hasProp(this, 'selectedKeys') && index !== -1) {
|
|
|
|
sSelectedKeys.splice(index, 1)
|
2017-12-12 13:49:02 +08:00
|
|
|
}
|
2018-01-02 19:05:02 +08:00
|
|
|
index = sOpenKeys.indexOf(key)
|
|
|
|
if (!hasProp(this, 'openKeys') && index !== -1) {
|
|
|
|
sOpenKeys.splice(index, 1)
|
2017-12-12 13:49:02 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
onSelect (selectInfo) {
|
|
|
|
const props = this.$props
|
|
|
|
if (props.selectable) {
|
|
|
|
// root menu
|
2018-01-02 19:05:02 +08:00
|
|
|
let sSelectedKeys = this.$data.sSelectedKeys
|
2017-12-12 13:49:02 +08:00
|
|
|
const selectedKey = selectInfo.key
|
|
|
|
if (props.multiple) {
|
2018-01-02 19:05:02 +08:00
|
|
|
sSelectedKeys = sSelectedKeys.concat([selectedKey])
|
2017-12-12 13:49:02 +08:00
|
|
|
} else {
|
2018-01-02 19:05:02 +08:00
|
|
|
sSelectedKeys = [selectedKey]
|
2017-12-12 13:49:02 +08:00
|
|
|
}
|
2018-01-02 19:05:02 +08:00
|
|
|
if (!hasProp(this, 'selectedKeys')) {
|
2017-12-12 13:49:02 +08:00
|
|
|
this.setState({
|
2018-01-02 19:05:02 +08:00
|
|
|
sSelectedKeys,
|
2017-12-12 13:49:02 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
this.$emit('select', {
|
|
|
|
...selectInfo,
|
2018-01-02 19:05:02 +08:00
|
|
|
sSelectedKeys,
|
2017-12-12 13:49:02 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
onClick (e) {
|
|
|
|
this.$emit('click', e)
|
|
|
|
},
|
|
|
|
|
|
|
|
onOpenChange (e_) {
|
2018-01-02 19:05:02 +08:00
|
|
|
const sOpenKeys = this.$data.sOpenKeys.concat()
|
2017-12-12 13:49:02 +08:00
|
|
|
let changed = false
|
|
|
|
const processSingle = (e) => {
|
|
|
|
let oneChanged = false
|
|
|
|
if (e.open) {
|
2018-01-02 19:05:02 +08:00
|
|
|
oneChanged = sOpenKeys.indexOf(e.key) === -1
|
2017-12-12 13:49:02 +08:00
|
|
|
if (oneChanged) {
|
2018-01-02 19:05:02 +08:00
|
|
|
sOpenKeys.push(e.key)
|
2017-12-12 13:49:02 +08:00
|
|
|
}
|
|
|
|
} else {
|
2018-01-02 19:05:02 +08:00
|
|
|
const index = sOpenKeys.indexOf(e.key)
|
2017-12-12 13:49:02 +08:00
|
|
|
oneChanged = index !== -1
|
|
|
|
if (oneChanged) {
|
2018-01-02 19:05:02 +08:00
|
|
|
sOpenKeys.splice(index, 1)
|
2017-12-12 13:49:02 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
changed = changed || oneChanged
|
|
|
|
}
|
|
|
|
if (Array.isArray(e_)) {
|
|
|
|
// batch change call
|
|
|
|
e_.forEach(processSingle)
|
|
|
|
} else {
|
|
|
|
processSingle(e_)
|
|
|
|
}
|
|
|
|
if (changed) {
|
2018-01-02 19:05:02 +08:00
|
|
|
if (!hasProp(this, 'openKeys')) {
|
|
|
|
this.setState({ sOpenKeys })
|
2017-12-12 13:49:02 +08:00
|
|
|
}
|
2018-01-02 19:05:02 +08:00
|
|
|
this.$emit('openChange', sOpenKeys)
|
2017-12-12 13:49:02 +08:00
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
onDeselect (selectInfo) {
|
|
|
|
const props = this.$props
|
|
|
|
if (props.selectable) {
|
2018-01-02 19:05:02 +08:00
|
|
|
const sSelectedKeys = this.$data.sSelectedKeys.concat()
|
2017-12-12 13:49:02 +08:00
|
|
|
const selectedKey = selectInfo.key
|
2018-01-02 19:05:02 +08:00
|
|
|
const index = sSelectedKeys.indexOf(selectedKey)
|
2017-12-12 13:49:02 +08:00
|
|
|
if (index !== -1) {
|
2018-01-02 19:05:02 +08:00
|
|
|
sSelectedKeys.splice(index, 1)
|
2017-12-12 13:49:02 +08:00
|
|
|
}
|
2018-01-02 19:05:02 +08:00
|
|
|
if (!hasProp(this, 'selectedKeys')) {
|
2017-12-12 13:49:02 +08:00
|
|
|
this.setState({
|
2018-01-02 19:05:02 +08:00
|
|
|
sSelectedKeys,
|
2017-12-12 13:49:02 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
this.$emit('deselect', {
|
|
|
|
...selectInfo,
|
2018-01-02 19:05:02 +08:00
|
|
|
sSelectedKeys,
|
2017-12-12 13:49:02 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
getOpenTransitionName () {
|
|
|
|
const props = this.$props
|
|
|
|
let transitionName = props.openTransitionName
|
|
|
|
const animationName = props.openAnimation
|
|
|
|
if (!transitionName && typeof animationName === 'string') {
|
|
|
|
transitionName = `${props.prefixCls}-open-${animationName}`
|
|
|
|
}
|
|
|
|
return transitionName
|
|
|
|
},
|
|
|
|
|
|
|
|
isInlineMode () {
|
|
|
|
return this.$props.mode === 'inline'
|
|
|
|
},
|
|
|
|
|
|
|
|
lastOpenSubMenu () {
|
|
|
|
let lastOpen = []
|
2018-01-02 19:05:02 +08:00
|
|
|
const { sOpenKeys } = this.$data
|
|
|
|
if (sOpenKeys.length) {
|
2017-12-12 13:49:02 +08:00
|
|
|
lastOpen = this.getFlatInstanceArray().filter((c) => {
|
2018-01-09 14:21:15 +08:00
|
|
|
return c && sOpenKeys.indexOf(c.eventKey) !== -1
|
2017-12-12 13:49:02 +08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
return lastOpen[0]
|
|
|
|
},
|
|
|
|
|
|
|
|
renderMenuItem (c, i, subIndex) {
|
|
|
|
if (!c) {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
const state = this.$data
|
|
|
|
const extraProps = {
|
2018-01-02 19:05:02 +08:00
|
|
|
openKeys: state.sOpenKeys,
|
|
|
|
selectedKeys: state.sSelectedKeys,
|
2017-12-12 13:49:02 +08:00
|
|
|
triggerSubMenuAction: this.$props.triggerSubMenuAction,
|
2018-01-03 18:30:12 +08:00
|
|
|
isRootMenu: true,
|
2017-12-12 13:49:02 +08:00
|
|
|
}
|
|
|
|
return this.renderCommonMenuItem(c, i, subIndex, extraProps)
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
render () {
|
|
|
|
const props = { ...this.$props }
|
2018-01-02 19:05:02 +08:00
|
|
|
props.class = ` ${props.prefixCls}-root`
|
2018-01-03 18:30:12 +08:00
|
|
|
return this.renderRoot(props, this.$slots.default)
|
2017-12-12 13:49:02 +08:00
|
|
|
},
|
|
|
|
}
|
|
|
|
export default Menu
|
|
|
|
</script>
|