add menu-list

pull/9263/head
baiyaaaaa 2018-01-18 12:22:23 +08:00
parent 5387b99e5b
commit 5799df9bf2
3 changed files with 115 additions and 61 deletions

View File

@ -0,0 +1,96 @@
<script>
import ElCollapseTransition from 'element-ui/src/transitions/collapse-transition';
import menuMixin from './menu-mixin';
import Popper from 'element-ui/src/utils/vue-popper';
export default {
name: 'ElMenuList',
mixins: [menuMixin, Popper],
components: { ElCollapseTransition },
computed: {
menuTransitionName() {
return this.rootMenu.collapse ? 'el-zoom-in-left' : 'el-zoom-in-top';
}
},
props: {
transformOrigin: {
type: [Boolean, String],
default: false
},
menuPopup: {
type: Boolean,
default: false
},
visible: {
type: Boolean,
default: false
}
},
watch: {
visible(val) {
if (this.menuPopup) {
this.$nextTick(_ => {
this.showPopper = val;
});
}
}
},
methods: {
initPopper() {
this.referenceElm = this.$parent.$el;
this.popperElm = this.$el;
}
},
mounted() {
this.initPopper();
},
render(h) {
const {
rootMenu,
placement,
$slots,
visible
} = this;
const popupMenu = (
<transition name={this.menuTransitionName}>
<div
ref="menu"
v-show={visible}
class={[`el-menu--${rootMenu.mode}`]}
on-mouseenter={() => { this.$emit('mouseenter'); }}
on-mouseleave={() => { this.$emit('mouseleave'); }}
on-focus={() => { this.$emit('mouseenter'); }}>
<ul
role="menu"
class={['el-menu el-menu--popup', `el-menu--popup-${placement}`]}
style={{ backgroundColor: rootMenu.backgroundColor || '' }}>
{$slots.default}
</ul>
</div>
</transition>
);
const inlineMenu = (
<el-collapse-transition>
<ul
v-show={visible}
role="menu"
class="el-menu el-menu--inline"
style={{ backgroundColor: rootMenu.backgroundColor || '' }}>
{$slots.default}
</ul>
</el-collapse-transition>
);
return this.menuPopup ? popupMenu : inlineMenu;
}
}
</script>

View File

@ -3,6 +3,7 @@
import menuMixin from './menu-mixin'; import menuMixin from './menu-mixin';
import Emitter from 'element-ui/src/mixins/emitter'; import Emitter from 'element-ui/src/mixins/emitter';
import Popper from 'element-ui/src/utils/vue-popper'; import Popper from 'element-ui/src/utils/vue-popper';
import MenuList from './menu-list';
export default { export default {
name: 'ElSubmenu', name: 'ElSubmenu',
@ -11,13 +12,9 @@
mixins: [menuMixin, Emitter, Popper], mixins: [menuMixin, Emitter, Popper],
components: { ElCollapseTransition }, components: { ElCollapseTransition, MenuList },
props: { props: {
transformOrigin: {
type: [Boolean, String],
default: false
},
index: { index: {
type: String, type: String,
required: true required: true
@ -105,17 +102,12 @@
? this.activeTextColor ? this.activeTextColor
: this.textColor : this.textColor
}; };
},
popperPlacement() {
return this.mode === 'horizontal' ? 'bottom-start' : 'right-start';
} }
}, },
methods: { methods: {
handleCollapseToggle(value) {
if (value) {
this.initPopper();
} else {
this.doDestroy();
document.body.removeChild(this.popperElm);
}
},
addItem(item) { addItem(item) {
this.$set(this.items, item.index, item); this.$set(this.items, item.index, item);
}, },
@ -173,23 +165,11 @@
if (this.mode === 'horizontal' && !this.rootMenu.backgroundColor) return; if (this.mode === 'horizontal' && !this.rootMenu.backgroundColor) return;
const title = this.$refs['submenu-title']; const title = this.$refs['submenu-title'];
title && (title.style.backgroundColor = this.rootMenu.backgroundColor || ''); title && (title.style.backgroundColor = this.rootMenu.backgroundColor || '');
},
updatePlacement() {
this.currentPlacement = this.mode === 'horizontal' ? 'bottom-start' : 'right-start';
},
initPopper() {
this.referenceElm = this.$el;
this.popperElm = this.$refs.menu;
this.updatePlacement();
} }
}, },
created() { created() {
this.parentMenu.addSubmenu(this); this.parentMenu.addSubmenu(this);
this.rootMenu.addSubmenu(this); this.rootMenu.addSubmenu(this);
this.$on('toggle-collapse', this.handleCollapseToggle);
},
mounted() {
this.initPopper();
}, },
beforeDestroy() { beforeDestroy() {
this.parentMenu.removeSubmenu(this); this.parentMenu.removeSubmenu(this);
@ -204,42 +184,10 @@
backgroundColor, backgroundColor,
$slots, $slots,
rootMenu, rootMenu,
currentPlacement, isMenuPopup,
menuTransitionName,
mode mode
} = this; } = this;
const popupMenu = (
<transition name={menuTransitionName}>
<div
ref="menu"
v-show={opened}
class={[`el-menu--${mode}`]}
on-mouseenter={this.handleMouseenter}
on-mouseleave={this.handleMouseleave}
on-focus={this.handleMouseenter}>
<ul
role="menu"
class={['el-menu el-menu--popup', `el-menu--popup-${currentPlacement}`]}
style={{ backgroundColor: rootMenu.backgroundColor || '' }}>
{$slots.default}
</ul>
</div>
</transition>
);
const inlineMenu = (
<el-collapse-transition>
<ul
role="menu"
class="el-menu el-menu--inline"
v-show={opened}
style={{ backgroundColor: rootMenu.backgroundColor || '' }}>
{$slots.default}
</ul>
</el-collapse-transition>
);
return ( return (
<li <li
class={{ class={{
@ -270,7 +218,15 @@
}}> }}>
</i> </i>
</div> </div>
{this.isMenuPopup ? popupMenu : inlineMenu} <MenuList
visible={opened}
menu-popup={isMenuPopup}
append-to-body={isMenuPopup && this.$parent === rootMenu}
placement={this.popperPlacement}
on-mouseenter={this.handleMouseenter}
on-mouseleave={this.handleMouseleave}>
{$slots.default}
</MenuList>
</li> </li>
); );
} }

View File

@ -103,6 +103,9 @@
border-bottom: 2px solid $--color-primary; border-bottom: 2px solid $--color-primary;
color: $--color-text-primary; color: $--color-text-primary;
} }
& .el-menu--popup {
padding: 5px 0;
}
} }
@include m(collapse) { @include m(collapse) {
width: 64px; width: 64px;
@ -159,10 +162,9 @@
z-index: 100; z-index: 100;
min-width: 200px; min-width: 200px;
border: none; border: none;
padding: 5px 0;
border-radius: $--border-radius-small; border-radius: $--border-radius-small;
box-shadow: $--box-shadow-light; box-shadow: $--box-shadow-light;
overflow: hidden; // overflow: hidden;
&-bottom-start { &-bottom-start {
margin-top: 5px; margin-top: 5px;