<template>
|
<div class="menu" :class="{ collapse: menuData.collapse }">
|
<scrollbar>
|
<el-menu
|
ref="menu"
|
:key="menuRenderKey"
|
:default-active="activeMenuIndex"
|
text-color="#333333"
|
active-text-color="#207FF7"
|
:collapse="menuData.collapse"
|
:default-openeds="openMenuIndexes"
|
:collapse-transition="false"
|
unique-opened
|
@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, mapMutations } from 'vuex'
|
import MenuItems from './MenuItems'
|
import Scrollbar from './Scrollbar'
|
import { findMenuByRoute } from '@/utils/menuRoute'
|
|
export default {
|
name: 'Menu',
|
components: { Scrollbar, MenuItems },
|
data () {
|
return {
|
activeMenuIndex: '',
|
openMenuIndexes: [],
|
menuRenderKey: 0
|
}
|
},
|
computed: {
|
...mapState(['menuData', 'topMenuList'])
|
},
|
watch: {
|
'$route' () {
|
this.syncMenuFromRoute()
|
},
|
'menuData.list' () {
|
this.syncMenuFromRoute()
|
}
|
},
|
mounted () {
|
this.syncMenuFromRoute()
|
},
|
methods: {
|
...mapMutations(['pushtags', 'syncTopMenuFromRoute']),
|
syncMenuFromRoute () {
|
const path = this.normalizePath(this.$route.path)
|
const menuIndex = this.$route.query.index
|
const result = findMenuByRoute(this.topMenuList.list, path, menuIndex)
|
if (result == null) {
|
return
|
}
|
if (result.topMenu.id !== this.$store.state.topMenuCurrent.id) {
|
this.syncTopMenuFromRoute({
|
topMenu: result.topMenu,
|
topIndex: result.topIndex
|
})
|
}
|
this.activeMenuIndex = result.menu.index
|
this.openMenuIndexes = result.parents.map(item => item.index)
|
this.menuRenderKey += 1
|
this.pushtags(result.menu)
|
this.$nextTick(() => {
|
this.openParentMenus()
|
})
|
},
|
openParentMenus () {
|
const menuRef = this.$refs.menu
|
if (!menuRef || this.openMenuIndexes.length === 0) {
|
return
|
}
|
this.openMenuIndexes.forEach(index => {
|
if (typeof menuRef.open === 'function') {
|
menuRef.open(index)
|
}
|
})
|
},
|
normalizePath (path) {
|
if (path == null || path === '') {
|
return ''
|
}
|
return path.endsWith('/') ? path.substring(0, path.length - 1) : path
|
},
|
// 处理菜单选中
|
handleSelect (menuIndex) {
|
const menuConfig = this.__getMenuConfig(menuIndex, 'index', this.menuData.list)
|
if (menuConfig == null) {
|
return
|
}
|
// 找不到页面
|
try {
|
require('@/views' + menuConfig.url)
|
} catch (e) {
|
this.$tip.error('未找到页面文件@/views' + menuConfig.url + '.vue,请检查菜单路径是否正确')
|
return
|
}
|
// 点击当前菜单不做处理
|
if (menuConfig.url === this.$route.path && (menuConfig.params == null || menuConfig.params === undefined || menuConfig.params === '' || menuConfig.params === this.$route.query.param)) {
|
return
|
}
|
if (menuConfig.url == null || menuConfig.url.trim().length === 0) {
|
return
|
}
|
|
this.$router.push({ path: menuConfig.url, query: { index: menuConfig.index, param: menuConfig.params, time: (Math.random().toString()) } })
|
this.pushtags(menuConfig)
|
},
|
// 获取菜单配置
|
__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
|
},
|
computeTableHeight () {
|
this.$nextTick(() => {
|
const height = window.innerHeight
|
const height13 = this.getEleHeghtByClassName('common-header', 0)
|
const height5 = document.getElementsByTagName('thead') && document.getElementsByTagName('thead')[0] ? document.getElementsByTagName('thead')[0].clientHeight : 0
|
if (document.getElementsByClassName('main_app') && document.getElementsByClassName('main_app')[0]) {
|
const height3 = this.getEleHeghtByClassName('main-header', 0)
|
const height4 = this.getEleHeghtByClassName('table-pagination', 0)
|
const height2 = this.getEleHeghtByClassName('toolbar', 0)
|
const height6 = this.getEleHeghtByClassName('doumee-filter', 0, 16)
|
const height7 = this.getEleHeghtByClassName('pt16', 0, 0)
|
const height9 = this.getEleHeghtByClassName('static_wrap', 0)
|
const height10 = this.getEleHeghtByClassName('query_btns', 0)
|
const height11 = this.getEleHeghtByClassName('el-tabs-ele', 0)
|
const height12 = this.getEleHeghtByClassName('platgroup_tabs', 0)
|
this.$router.app.$store.commit('setTableHeightNew', height - height13 - height3 - height5 - height6 - height2 - height7 - height4 - height9 - height10 - height11 - height12)
|
} else {
|
const height1 = this.getEleHeghtByClassName('table-search-form', 40, 16)
|
const height3 = this.getEleHeghtByClassName('main-header', 0)
|
const height4 = this.getEleHeghtByClassName('table-pagination', 0)
|
const height2 = this.getEleHeghtByClassName('toolbar', 0)
|
this.$router.app.$store.commit('setTableHeightNew', height - height4 - height3 - height2 - height1 - height5 - height13)
|
}
|
})
|
},
|
getEleHeghtByClassName (name, dv, margin) {
|
if ((document.getElementsByClassName(name) && document.getElementsByClassName(name)[0])) {
|
let t = 0
|
document.getElementsByClassName(name).forEach(e => {
|
t++
|
})
|
return document.getElementsByClassName(name)[document.getElementsByClassName(name).length - 1].clientHeight + (margin || 0)
|
}
|
return dv || 0
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
@import "@/assets/style/variables.scss";
|
.menu {
|
height: 100%;
|
display: flex;
|
flex-direction: column;
|
}
|
</style>
|
<style lang="scss">
|
@import "@/assets/style/variables.scss";
|
// 菜单样式
|
.el-menu {
|
border-right: 0 !important;
|
user-select: none;
|
background: #fff !important;
|
.el-menu-item {
|
background: #fff;
|
height: 48px;
|
line-height: 48px;
|
// 选中状态
|
&.is-active {
|
background: #eff5fe !important;
|
}
|
// 悬浮
|
&:hover {
|
background-color: #eff5fe;
|
}
|
&:focus {
|
background: #eff5fe;
|
}
|
}
|
// 子菜单
|
.el-submenu {
|
.el-submenu__title {
|
background-color: #fff;
|
}
|
&.is-active {
|
.el-submenu__title {
|
background-color: #fff;
|
}
|
.el-menu .el-menu-item {
|
background-color: #fff;
|
// 悬浮
|
&:hover {
|
background-color: #eff5fe;
|
}
|
}
|
}
|
// 菜单上下箭头
|
.el-submenu__title i {
|
color: #979797;
|
font-size: 14px;
|
}
|
}
|
// 菜单图标
|
i:not(.el-submenu__icon-arrow) {
|
color: #333333 !important;
|
position: relative;
|
top: -1px;
|
// 自定义图标
|
&[class^="eva-icon-"] {
|
width: 24px;
|
margin-right: 5px;
|
background-size: 15px;
|
}
|
}
|
}
|
</style>
|