<template>
|
<div class="menu" :class="{collapse: menuData.collapse}">
|
<div class="logo">
|
<div><img src="@/assets/logo.png"></div>
|
<h1 :class="{hidden: menuData.collapse}">近快后台管理系统</h1>
|
</div>
|
<scrollbar>
|
<el-menu
|
ref="menu"
|
:default-active="activeIndex"
|
text-color="#fff"
|
active-text-color="#fff"
|
:collapse="menuData.collapse"
|
:default-openeds="defaultOpeneds"
|
:collapse-transition="false"
|
@select="handleSelect"
|
>
|
<MenuItems v-for="menu in menuData.list" :key="menu.index" :menu="menu" :is-root-menu="true"/>
|
</el-menu>
|
</scrollbar>
|
</div>
|
</template>
|
|
<script>
|
import { mapState } from 'vuex'
|
import MenuItems from './MenuItems'
|
import Scrollbar from './Scrollbar'
|
export default {
|
name: 'Menu',
|
components: { Scrollbar, MenuItems },
|
computed: {
|
...mapState(['menuData']),
|
// 选中的菜单index
|
activeIndex () {
|
let path = this.$route.path
|
if (path.endsWith('/')) {
|
path = path.substring(0, path.length - 1)
|
}
|
const menuConfig = this.__getMenuConfig(path, 'url', this.menuData.list)
|
if (menuConfig == null) {
|
return null
|
}
|
return menuConfig.index
|
},
|
// 默认展开的菜单index
|
defaultOpeneds () {
|
return this.menuData.list.map(menu => menu.index)
|
}
|
},
|
methods: {
|
/**
|
* 处理菜单选中
|
*
|
* @param menuIndex 选中的菜单索引
|
*/
|
handleSelect (menuIndex) {
|
const menuConfig = this.__getMenuConfig(menuIndex, 'index', this.menuData.list)
|
// 找不到页面
|
try {
|
require('@/views' + menuConfig.url)
|
} catch (e) {
|
this.$tip.error('未找到页面文件@/views' + menuConfig.url + '.vue,请检查菜单路径是否正确')
|
}
|
// 点击当前菜单不做处理
|
if (menuConfig.url === this.$route.path) {
|
return
|
}
|
if (menuConfig.url == null || menuConfig.url.trim().length === 0) {
|
return
|
}
|
this.$router.push(menuConfig.url)
|
},
|
/**
|
* 获取菜单配置
|
*
|
* @param value 唯一标识值
|
* @param key 唯一标识key
|
* @param menus 查找菜单范围
|
* @returns {null|*|null}
|
* @private
|
*/
|
__getMenuConfig (value, key, menus) {
|
for (const menu of menus) {
|
if (menu[key] === value) {
|
return menu
|
}
|
if (menu.children != null && menu.children.length > 0) {
|
const menuConfig = this.__getMenuConfig(value, key, menu.children)
|
if (menuConfig != null) {
|
return menuConfig
|
}
|
}
|
}
|
return null
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
@import "@/assets/style/variables.scss";
|
.menu {
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
// LOGO
|
.logo {
|
height: 60px;
|
flex-shrink: 0;
|
line-height: 60px;
|
overflow: hidden;
|
display: flex;
|
background: $primary-color - 20;
|
padding: 0 16px;
|
& > div {
|
width: 32px;
|
flex-shrink: 0;
|
margin-right: 12px;
|
img {
|
width: 100%;
|
flex-shrink: 0;
|
vertical-align: middle;
|
position: relative;
|
top: -2px;
|
}
|
}
|
h1 {
|
font-size: 16px;
|
font-weight: 500;
|
transition: opacity ease .3s;
|
overflow: hidden;
|
&.hidden {
|
opacity: 0;
|
}
|
}
|
}
|
}
|
</style>
|
<style lang="scss">
|
@import "@/assets/style/variables.scss";
|
// 菜单样式
|
.el-menu {
|
border-right: 0 !important;
|
user-select: none;
|
background: $primary-color !important;
|
.el-menu-item {
|
background: $primary-color;
|
// 选中状态
|
&.is-active {
|
background: $primary-color - 40 !important;
|
}
|
// 悬浮
|
&:hover {
|
background-color: $primary-color - 12;
|
}
|
&:focus {
|
background: $primary-color;
|
}
|
}
|
// 子菜单
|
.el-submenu {
|
.el-submenu__title{
|
background-color: $primary-color;
|
}
|
&.is-active {
|
.el-submenu__title{
|
background-color: $primary-color - 20;
|
}
|
.el-menu .el-menu-item{
|
background-color: $primary-color - 20;
|
// 悬浮
|
&:hover {
|
background-color: $primary-color - 30;
|
}
|
}
|
}
|
// 菜单上下箭头
|
.el-submenu__title i {
|
color: #f7f7f7;
|
}
|
}
|
// 菜单图标
|
i:not(.el-submenu__icon-arrow) {
|
color: #f7f7f7 !important;
|
position: relative;
|
top: -1px;
|
// 自定义图标
|
&[class^="eva-icon-"] {
|
width: 24px;
|
margin-right: 5px;
|
background-size: 15px;
|
}
|
}
|
}
|
</style>
|