mirror of https://github.com/ElemeFE/element
144 lines
3.6 KiB
Vue
144 lines
3.6 KiB
Vue
<template>
|
|
<ul class="el-menu"
|
|
:class="{
|
|
'el-menu--horizontal': mode === 'horizontal',
|
|
'el-menu--dark': theme === 'dark'
|
|
}"
|
|
>
|
|
<slot></slot>
|
|
</ul>
|
|
</template>
|
|
<script>
|
|
import emitter from 'element-ui/src/mixins/emitter';
|
|
|
|
export default {
|
|
name: 'ElMenu',
|
|
|
|
componentName: 'ElMenu',
|
|
|
|
mixins: [emitter],
|
|
|
|
props: {
|
|
mode: {
|
|
type: String,
|
|
default: 'vertical'
|
|
},
|
|
defaultActive: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
defaultOpeneds: Array,
|
|
theme: {
|
|
type: String,
|
|
default: 'light'
|
|
},
|
|
uniqueOpened: Boolean,
|
|
router: Boolean,
|
|
menuTrigger: {
|
|
type: String,
|
|
default: 'hover'
|
|
}
|
|
},
|
|
data() {
|
|
return {
|
|
activedIndex: this.defaultActive,
|
|
openedMenus: this.defaultOpeneds ? this.defaultOpeneds.slice(0) : [],
|
|
items: {},
|
|
submenus: {}
|
|
};
|
|
},
|
|
watch: {
|
|
defaultActive(value) {
|
|
const item = this.items[value];
|
|
if (!item) return;
|
|
|
|
this.activedIndex = item.index;
|
|
this.initOpenedMenu();
|
|
},
|
|
defaultOpeneds(value) {
|
|
this.openedMenus = value;
|
|
}
|
|
},
|
|
methods: {
|
|
addItem(item) {
|
|
this.$set(this.items, item.index, item);
|
|
},
|
|
removeItem(item) {
|
|
delete this.items[item.index];
|
|
},
|
|
addSubmenu(item) {
|
|
this.$set(this.submenus, item.index, item);
|
|
},
|
|
removeSubmenu(item) {
|
|
delete this.submenus[item.index];
|
|
},
|
|
openMenu(index, indexPath) {
|
|
let openedMenus = this.openedMenus;
|
|
if (openedMenus.indexOf(index) !== -1) return;
|
|
// 将不在该菜单路径下的其余菜单收起
|
|
if (this.uniqueOpened) {
|
|
this.openedMenus = openedMenus.filter(index => {
|
|
return indexPath.indexOf(index) !== -1;
|
|
});
|
|
}
|
|
this.openedMenus.push(index);
|
|
},
|
|
closeMenu(index, indexPath) {
|
|
this.openedMenus.splice(this.openedMenus.indexOf(index), 1);
|
|
},
|
|
handleSubmenuClick(submenu) {
|
|
const { index, indexPath } = submenu;
|
|
let isOpened = this.openedMenus.indexOf(index) !== -1;
|
|
|
|
if (isOpened) {
|
|
this.closeMenu(index, indexPath);
|
|
this.$emit('close', index, indexPath);
|
|
} else {
|
|
this.openMenu(index, indexPath);
|
|
this.$emit('open', index, indexPath);
|
|
}
|
|
},
|
|
handleItemClick(item) {
|
|
let { index, indexPath } = item;
|
|
this.activedIndex = item.index;
|
|
this.$emit('select', index, indexPath, item);
|
|
|
|
if (this.mode === 'horizontal') {
|
|
this.openedMenus = [];
|
|
}
|
|
|
|
if (this.router) {
|
|
this.routeToItem(item);
|
|
}
|
|
},
|
|
// 初始化展开菜单
|
|
initOpenedMenu() {
|
|
const index = this.activedIndex;
|
|
const activeItem = this.items[index];
|
|
if (!activeItem || this.mode === 'horizontal') return;
|
|
|
|
let indexPath = activeItem.indexPath;
|
|
|
|
// 展开该菜单项的路径上所有子菜单
|
|
indexPath.forEach(index => {
|
|
let submenu = this.submenus[index];
|
|
submenu && this.openMenu(index, submenu.indexPath);
|
|
});
|
|
},
|
|
routeToItem(item) {
|
|
let route = item.route || item.index;
|
|
try {
|
|
this.$router.push(route);
|
|
} catch (e) {
|
|
console.error(e);
|
|
}
|
|
}
|
|
},
|
|
mounted() {
|
|
this.initOpenedMenu();
|
|
this.$on('item-click', this.handleItemClick);
|
|
this.$on('submenu-click', this.handleSubmenuClick);
|
|
}
|
|
};
|
|
</script>
|