基于vue-element-admin实现的可切换至顶部菜单栏
·
https://panjiachen.gitee.io/vue-element-admin/#
我们基于vue-element-admin框架可看出官网只支持侧边菜单栏样式,而系统开发时要求基于顶部菜单栏的样式,这个时候就需要进行改造一番。
1.@/styles/sidebar.scss 修改.hideSidebar 的样式
.hideSidebar {
.sidebar-container {
width: $hideSidebar !important; //默认54px,收起时会展示图标,因此我们设为0
}
.main-container {
margin-left: $hideSidebar; //默认54px,收起时会留出 54px 的空白,因此我们设为0
}
.submenu-title-noDropdown {
padding: 0 !important;
position: relative;
.el-tooltip {
padding: 0 !important;
.svg-icon {
margin-left: $hideSidebarSvg;
}
}
}
// .sidebar-container {
// width: 54px !important;
// }
// .main-container {
// margin-left: 54px;
// }
// .submenu-title-noDropdown {
// padding: 0 !important;
// position: relative;
// .el-tooltip {
// padding: 0 !important;
// .svg-icon {
// margin-left: 20px;
// }
// }
// }
.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
在index.js中声明组件
@/views/layout/HeadNavbar/index.vue 将template修改如下:
@/views/layout/HeadNavbar/SidebarItem.vue 将template修改如下:
<template>
<!-- style设置为inline-block,避免标题垂直布局-->
<div v-if="!item.hidden" style="display:inline-block;">
<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)">
<item :title="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" :title="item.meta.title" :icon="item.meta && item.meta.icon"/>
<!-- 增加固定宽度解决箭头被遮挡的问题-->
<div style="display: inline-block; width:20px;"></div>
</template>
<vertical-item
v-for="child in item.children"
:key="child.path"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
/>
</el-submenu>
</div>
</template>
<script>
import path from 'path'
import { isExternal } from '@/utils/validate'
import Item from './Item'
import AppLink from './Link'
import FixiOSBug from './FixiOSBug'
import VerticalItem from './VerticalItem'
export default {
name: 'SidebarItem',
components: { Item, AppLink,VerticalItem },
mixins: [FixiOSBug],
props: {
// route object
item: {
type: Object,
required: true
},
isNest: {
type: Boolean,
default: false
},
basePath: {
type: String,
default: ''
}
},
data() {
// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
// TODO: refactor with render function
this.onlyOneChild = null
return {}
},
methods: {
hasOneShowingChild(children = [], parent) {
const showingChildren = children.filter(item => {
if (item.hidden) {
return false
} else {
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item
return true
}
})
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
return true
}
return false
},
resolvePath(routePath) {
if (isExternal(routePath)) {
return routePath
}
if (isExternal(this.basePath)) {
return this.basePath
}
return path.resolve(this.basePath, routePath)
}
}
}
</script>
/views/layout/HeadNavbar/VerticalItem.vue 顶部导航栏不需要显示图标,将template修改如下:
<template>
<div v-if="!item.hidden" >
<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)">
<item :title="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" :title="item.meta.title"/>
</template>
<vertical-item
v-for="child in item.children"
:key="child.path"
:is-nest="true"
:item="child"
:base-path="resolvePath(child.path)"
/>
</el-submenu>
</div>
</template>
<script>
import path from 'path'
import { isExternal } from '@/utils/validate'
import Item from './Item'
import AppLink from './Link'
import FixiOSBug from './FixiOSBug'
import VerticalItem from './VerticalItem'
export default {
name: 'SidebarItem',
components: { Item, AppLink,VerticalItem },
mixins: [FixiOSBug],
props: {
// route object
item: {
type: Object,
required: true
},
isNest: {
type: Boolean,
default: false
},
basePath: {
type: String,
default: ''
}
},
data() {
// To fix https://github.com/PanJiaChen/vue-admin-template/issues/237
// TODO: refactor with render function
this.onlyOneChild = null
return {}
},
methods: {
hasOneShowingChild(children = [], parent) {
const showingChildren = children.filter(item => {
if (item.hidden) {
return false
} else {
// Temp set(will be used if only has one showing child)
this.onlyOneChild = item
return true
}
})
// When there is only one child router, the child router is displayed by default
if (showingChildren.length === 1) {
return true
}
// Show parent if there are no child router to display
if (showingChildren.length === 0) {
this.onlyOneChild = { ... parent, path: '', noShowingChildren: true }
return true
}
return false
},
resolvePath(routePath) {
if (isExternal(routePath)) {
return routePath
}
if (isExternal(this.basePath)) {
return this.basePath
}
return path.resolve(this.basePath, routePath)
}
}
}
</script>
完成以上步骤以后顶部导航栏的组件就改造好了,只需要在index.vue 下引入就可以使用
<template>
<div :class="classObj" class="app-wrapper">
<div v-if="device==='mobile'&&sidebar.opened" class="drawer-bg" @click="handleClickOutside" />
<div class="main-container" :class="{ 'hyseNo':!meunStyle,'hyse':meunStyle,hasTagsView:needTagsView}" >
<div :class="{'fixed-header':fixedHeader,'hyfixedNo':fixedHeader,'hyfixed':!fixedHeader}" v-if="!meunStyle">
<sidebar class="sidebar-container" v-if="!meunStyle"/>
<navbar :style="`background:${theme};`"/>
<tags-view v-if="needTagsView" style="width:100%"/>
</div>
<div v-if="meunStyle">
<head-navbar v-if="meunStyle" />
<tags-view v-if="needTagsView" />
</div>
<app-main />
<right-panel v-if="showSettings">
<setting-style />
</right-panel>
</div>
</div>
</template>
```import ResizeMixin from './mixin/ResizeHandler'
import { mapState } from 'vuex'
import { getSystemSetting} from '@/api/user/systemSetting'
//import {getAreaCode} from '@/api/baseManager/sourceDevice'
import RightPanel from '@/components/RightPanel'
import { AppMain, Navbar, Sidebar, TagsView,HeadNavbar } from './components'
import settingStyle from './components/Settings'
export default {
name: 'Layout',
components: {
AppMain,
Navbar,
RightPanel,
settingStyle,
Sidebar,
HeadNavbar,
TagsView
},
mixins: [ResizeMixin],
computed: {
...mapState({
sidebar: state => state.app.sidebar,
device: state => state.app.device,
showSettings: state => state.settings.showSettings,
needTagsView: state => state.settings.tagsView,
fixedHeader: state => state.settings.fixedHeader,
meunStyle: state => state.settings.meunStyle,
theme: state => state.settings.theme,
}),
classObj() {
return {
hideSidebar: !this.sidebar.opened,
openSidebar: this.sidebar.opened,
withoutAnimation: this.sidebar.withoutAnimation,
mobile: this.device === 'mobile'
}
}
},
data(){
return {
// HoStyle:this.$store.state.settings.meunStyle==true?"margin-left:210px;":"margin-left:0px;",//根据是否显示顶部菜单栏,判断是否空置出左边菜单位置
areaCode:null,
mapurl:null,
coordinate:null,
listQuery:{
areaCode:undefined,
areaType:undefined
},
}
},
created(){
this.getSystem();
},
此处的${theme}是取的默认主题色,在
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200828164343888.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzU4MjgwNA==,size_16,color_FFFFFF,t_70#pic_center)
通过![在这里插入图片描述](https://img-blog.csdnimg.cn/20200828164400276.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zNzU4MjgwNA==,size_16,color_FFFFFF,t_70#pic_center)
这里定义,即可全局取到 theme: state => state.settings.theme,
我的实现是可以在设置里进行切换显示到底是顶部菜单显示还是侧边显示。
更多推荐
已为社区贡献1条内容
所有评论(0)