背景
基于vue-element-admin开发,需要控制切换导航菜单
最终效果
不改变导航栏与路由绑定的效果,自由切换侧边栏和顶部导航栏。
image.png
步骤
1.@/styles/sidebar.scss 修改.hideSidebar 的样式
.hideSidebar {
.sidebar-container {
width: 0 !important; //默认54px,收起时会展示图标,因此我们设为0
}
.main-container {
margin-left: 0; //默认54px,收起时会留出 54px 的空白,因此我们设为0
}
.submenu-title-noDropdown {
padding: 0 !important;
position: relative;
.el-tooltip {
padding: 0 !important;
.svg-icon {
margin-left: 20px;
}
}
}
/* 注释掉.hideSidebar的子样式.el-submenu,避免submenu样式失灵,原因很简单,就是这段代码会导致标题之间距离从原本的20px变成0*/
/* .el-submenu {
overflow: hidden;
&>.el-submenu__title {
padding: 0 !important;
.svg-icon {
margin-left: 20px;
}
.el-submenu__icon-arrow {
display: none;
}
}
}*/
.el-menu--collapse {
.el-submenu {
&>.el-submenu__title {
&>span {
height: 0;
width: 0;
overflow: hidden;
visibility: hidden;
display: inline-block;
}
}
}
}
}
2.
复制一份@/views/layout/Sidebar 组件,粘贴到相同路径下,更改组件名为HeadNavbar,并判断是左侧菜单还是顶部菜单
image.png
image.png
在index.js中声明组件
image.png
@/views/layout/HeadNavbar/index.vue 将template修改如下:
<template>
<div :class="{'has-logo':showLogo}">
<!-- 判断是否需要左侧菜单logo -->
<logo
v-if="showLogo&&this.sitePropery=='left'"
:collapse="isCollapse"
/>
<div>
<el-scrollbar wrap-class="scrollbar-wrapper">
<!-- 判断是否需要左侧菜单标题 -->
<div
v-if="this.sitePropery=='left'"
class="h5"
>{{title}}</div>
<el-menu
:default-active="activeMenu"
:background-color="variables.menuBg"
:text-color="variables.menuText"
:unique-opened="true"
:active-text-color="variables.menuActiveText"
:collapse-transition="false"
@select="handleSelect"
mode="horizontal"
>
<sidebar-item
v-for="route in permission_routes"
:key="route.path"
:item="route"
:base-path="route.path"
/>
</el-menu>
</el-scrollbar>
<div class="panel">
<span style="margin-right: 10px;">导航面板</span>
<el-link
:underline="false"
type="info"
v-for="item in this.pathList"
:key="item.path"
@click="handleOpen(item.path)"
style="margin:0 10px;"
>{{item.name}}</el-link>
</div>
</div>
</div>
</template>
<script>
import { mapGetters } from 'vuex'
import Logo from './Logo'
import SidebarItem from './SidebarItem'
import variables from '@/styles/qlm-uivariables.scss'
import { qlm_setValue } from '@/utils/qlm_store'
export default {
components: { SidebarItem, Logo },
data() {
return {
title: this.$t('system.title'),
pathList: [],
sitePropery: this.$store.getters.sitePropery.menuMode
// sitePropery: 'left'
}
},
created() {
//因为是新打开窗口,需要重新初始化数据
this.$store.dispatch("qlm_user/getUserInfo").then(
ret => {
let namearray = this.$store.getters.rolenames;
let name = ""
if (namearray != null && namearray.length > 0) {
name = namearray[0]
}
}
)
},
mounted() {
},
computed: {
...mapGetters([
'permission_routes',
'sidebar'
]),
activeMenu() {
const route = this.$route
const { meta, path } = route
// if set path, the sidebar will highlight the path you set
if (meta.activeMenu) {
return meta.activeMenu
}
return path
},
showLogo() {
return this.$store.state.qlm_settings.sidebarLogo
},
variables() {
return variables
},
isCollapse() {
return !this.sidebar.opened
},
},
methods: {
handleSelect(key, keyPath) {
localStorage.setItem('keyPath', key)
qlm_setValue("QLMPath", key)
},
handleOpen(path, keyPath) {
// this.$message.success(path)
this.$router.push(path)
},
},
}
</script>
<style lang="scss" scoped>
>>> .el-scrollbar__view {
display: flex;
// background-color: #182b5c;
// height: 112px;
.h5 {
height: 56px;
padding: 0 20px;
line-height: 56px;
color: #fff;
font-size: 20px;
font-weight: 600;
text-align: center;
background-color: #2386ee;
}
.el-menu {
flex: 1;
}
}
.panel {
background-color: #182b5c;
min-height: 56px;
line-height: 56px;
padding: 0 25px;
color: #bfcbd9;
}
>>> .el-scrollbar__wrap {
overflow: hidden;
margin-bottom: 0px !important;
}
.el-menu.el-menu--horizontal {
// border-bottom: 0;
border-bottom: solid 1px #111;
}
.icon-arrow {
>>> .el-submenu__icon-arrow {
position: static;
}
}
</style>
@/views/layout/HeadNavbar/SidebarItem.vue 将template修改如下:
<template>
<!-- style设置为inline-block,避免标题垂直布局-->
<div
v-if="!item.hidden"
style="display:inline-block;"
:class="{'icon-arrow':this.sitePropery=='top'}"
>
<template
v-if="hasOneShowingChild(item.children,item) && (!onlyOneChild.children||onlyOneChild.noShowingChildren)&&!item.alwaysShow"
>
<app-link
v-if="onlyOneChild.meta"
:to="resolvePath(onlyOneChild.path)"
>
<el-menu-item
:index="resolvePath(onlyOneChild.path)"
:class="{'submenu-title-noDropdown':!isNest}"
>
<item
:icon="onlyOneChild.meta.icon||(item.meta&&item.meta.icon)"
:title="generateTitle(onlyOneChild.meta.title)"
/>
</el-menu-item>
</app-link>
</template>
<el-submenu
v-else
ref="subMenu"
:index="resolvePath(item.path)"
popper-append-to-body
>
<template slot="title">
<item
v-if="item.meta"
:icon="item.meta.icon"
:title="generateTitle(item.meta.title)"
>
</item>
</template>
<sidebar-item
v-for="child in item.children"
:key="child.path"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
class="nest-menu"
/>
</el-submenu>
</div>
</template>
<style lang="scss">
.nest-menu {
display: block !important;
}
.el-submenu {
padding-right: 20px;
}
// .el-submenu__title {
// margin-right: 20px;
// }
.icon-arrow {
>>> .el-submenu__icon-arrow {
position: static;
}
}
</style>
3.完成以上步骤以后顶部导航栏的组件就改造好了,只需要在index.vue 下引入就可以使用。
<template>
<div
:class="classObj"
class="app-wrapper"
>
<div
v-if="device==='mobile'&&sidebar.opened"
class="drawer-bg"
@click="handleClickOutside"
/>
<!-- 判断是否左侧菜单 -->
<sidebar
v-if="this.sitePropery=='left'"
class="sidebar-container"
/>
<!-- 判断是否需要左侧菜单宽度 -->
<div
:class="{hasTagsView:needTagsView,'main-container':this.sitePropery=='left'}"
>
<div :class="{'fixed-header':fixedHeader}">
<navbar />
<!-- 判断是否顶部菜单 -->
<head-navbar v-if="this.sitePropery=='top'" />
<tags-view v-if="needTagsView" />
</div>
<app-main />
<right-panel v-if="showSettings">
<settings />
</right-panel>
</div>
</div>
</template>
<script>
import RightPanel from '@/components/RightPanel'
import { AppMain, Navbar, Settings, Sidebar, TagsView, HeadNavbar } from './components'
import ResizeMixin from './mixin/ResizeHandler'
import { mapState } from 'vuex'
export default {
name: 'Layout',
components: {
AppMain,
Navbar,
RightPanel,
Settings,
Sidebar,
TagsView,
HeadNavbar
},
网友评论