| | |
| | | <template> |
| | | <div class="menu" :class="{collapse: menuData.collapse}"> |
| | | <div class="logo"> |
| | | <div><img src="@/assets/logo.png"></div> |
| | | <h1 :class="{hidden: menuData.collapse}">{{title}}</h1> |
| | | </div> |
| | | <div class="menu" :class="{ collapse: menuData.collapse }"> |
| | | <scrollbar> |
| | | <!-- :default-openeds="defaultOpeneds"--> |
| | | <el-menu |
| | | ref="menu" |
| | | :unique-opened="true" |
| | | :default-active="activeIndex" |
| | | text-color="#fff" |
| | | active-text-color="#fff" |
| | | :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"/> |
| | | <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 { mapState, mapMutations } from 'vuex' |
| | | import MenuItems from './MenuItems' |
| | | import Scrollbar from './Scrollbar' |
| | | import { findMenuByRoute } from '@/utils/menuRoute' |
| | | |
| | | export default { |
| | | name: 'Menu', |
| | | data() { |
| | | components: { Scrollbar, MenuItems }, |
| | | data () { |
| | | return { |
| | | title: process.env.VUE_APP_TITLE |
| | | activeMenuIndex: '', |
| | | openMenuIndexes: [], |
| | | menuRenderKey: 0 |
| | | } |
| | | }, |
| | | 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 |
| | | ...mapState(['menuData', 'topMenuList']) |
| | | }, |
| | | watch: { |
| | | '$route' () { |
| | | this.syncMenuFromRoute() |
| | | }, |
| | | // 默认展开的菜单index |
| | | defaultOpeneds () { |
| | | return this.menuData.list.map(menu => menu.index) |
| | | '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) { |
| | | 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(menuConfig.url) |
| | | |
| | | this.$router.push({ path: menuConfig.url, query: { index: menuConfig.index, param: menuConfig.params, time: (Math.random().toString()) } }) |
| | | this.pushtags(menuConfig) |
| | | }, |
| | | // 获取菜单配置 |
| | | __getMenuConfig (value, key, menus) { |
| | |
| | | } |
| | | } |
| | | 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 |
| | | } |
| | | } |
| | | } |
| | |
| | | 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"> |
| | |
| | | .el-menu { |
| | | border-right: 0 !important; |
| | | user-select: none; |
| | | background: $primary-color !important; |
| | | background: #fff !important; |
| | | .el-menu-item { |
| | | background: $primary-color; |
| | | background: #fff; |
| | | height: 48px; |
| | | line-height: 48px; |
| | | // 选中状态 |
| | | &.is-active { |
| | | background: $primary-color - 40 !important; |
| | | background: #eff5fe !important; |
| | | } |
| | | // 悬浮 |
| | | &:hover { |
| | | background-color: $primary-color - 12; |
| | | background-color: #eff5fe; |
| | | } |
| | | &:focus { |
| | | background: $primary-color; |
| | | background: #eff5fe; |
| | | } |
| | | } |
| | | // 子菜单 |
| | | .el-submenu { |
| | | .el-submenu__title{ |
| | | background-color: $primary-color; |
| | | .el-submenu__title { |
| | | background-color: #fff; |
| | | } |
| | | &.is-active { |
| | | .el-submenu__title{ |
| | | background-color: $primary-color - 20; |
| | | .el-submenu__title { |
| | | background-color: #fff; |
| | | } |
| | | .el-menu .el-menu-item{ |
| | | background-color: $primary-color - 20; |
| | | .el-menu .el-menu-item { |
| | | background-color: #fff; |
| | | // 悬浮 |
| | | &:hover { |
| | | background-color: $primary-color - 30; |
| | | background-color: #eff5fe; |
| | | } |
| | | } |
| | | } |
| | | // 菜单上下箭头 |
| | | .el-submenu__title i { |
| | | color: #f7f7f7; |
| | | color: #979797; |
| | | font-size: 14px; |
| | | } |
| | | } |
| | | // 菜单图标 |
| | | i:not(.el-submenu__icon-arrow) { |
| | | color: #f7f7f7 !important; |
| | | color: #333333 !important; |
| | | position: relative; |
| | | top: -1px; |
| | | // 自定义图标 |