在 Vue + elementUi 开发中,在大部分后台管理系统都会选择实现 “ 单页面 ” 应用,简称:SPA
。但是实现单页面应用,页面布局显然很重要,在开发中,有时候需要,自己编写一个 单页面导航栏。本篇文章将简单展示! 案例仅供参考!
Tips: 虽然现如今,有着许多可以开箱即用的后台管理系统框架,如:
vue-admin、Vue element admin、PigX、Antd Pro Vue
等等。但是俗话说的好: “ 打铁还需自身硬 ”, 所以给需要自定义 单页面导航栏的小伙伴展示案例,希望能有所帮助!
运用 v-for 循环遍历给定的参数,按照指定参数渲染对应的 侧边导航栏。原理较为简单,直接上案例即可。
使用到 elementUi 的 NavMenu 导航菜单组件 ,点击了解详细使用规则!
> HTML模板
<template>
<div :class="$root.themeHomeChange === '1' ? 'riskControlCenter_light' : 'riskControlCenter'">
<div class="left">
<el-menu :default-active="$route.query.index"
class="el-menu-vertical"
:text-color="$root.themeHomeChange === '1' ? '#adadad' : '#64b6fa'"
@select="handleSelect"
:collapse="isCollapse"
unique-opened>
<div v-for="item in menuList" :key="item.index">
<el-menu-item v-if="item.children.length === 0" :index="item.index">
<i :class="item.icon">i>
<span slot="title">{{item.title}}span>
el-menu-item>
<el-submenu v-else :index="item.index">
<template slot="title">
<i :class="item.icon">i>
<span v-show="!isCollapse" slot="title">{{item.title}}span>
template>
<el-menu-item-group>
<div v-for="item1 in item.children" :key="item1.index">
<el-menu-item v-if="item1.children.length === 0" :index="item1.index">
<i :class="item1.icon">i>
<span slot="title">{{item1.title}}span>
el-menu-item>
<el-submenu v-else :index="item1.index">
<template slot="title">
<i :class="item1.icon">i>
<span v-show="!isCollapse" slot="title">{{item1.title}}span>
template>
<el-menu-item-group>
<div v-for="item2 in item1.children" :key="item2.index">
<el-menu-item v-if="item2.children.length === 0" :index="item2.index">
<i :class="item2.icon">i>
<span slot="title">{{item2.title}}span>
el-menu-item>
<el-submenu v-else :index="item2.index">
<template slot="title">
<i :class="item2.icon">i>
<span v-show="!isCollapse" slot="title">{{item2.title}}span>
template>
<el-menu-item-group>
<div v-for="item3 in item2.children" :key="item3.index">
<el-menu-item v-if="item3.children.length === 0" :index="item3.index">
<i :class="item3.icon">i>
<span slot="title">{{item3.title}}span>
el-menu-item>
div>
el-menu-item-group>
el-submenu>
div>
el-menu-item-group>
el-submenu>
div>
el-menu-item-group>
el-submenu>
div>
el-menu>
<el-button :icon="isCollapse ? 'el-icon-d-arrow-right' : 'el-icon-d-arrow-left'"
class="btnGroup"
@click="() => { isCollapse = !isCollapse; $forceUpdate() }"
type="primary"
>el-button>
div>
<div
class="right"
:style="{
'background': $root.themeHomeChange === '1' ? '#eef3ff' : '#05163d'
}"
ref="riskControlCenter">
div>
div>
template>
<script>
export default {
name: "riskControlCenter",
data(){
return {
isCollapse : true,
routerList: {},
menuList: [
{
title: '总览',
path: '/overView',
index: '3-1',
icon: 'el-icon-data-line',
children: []
},
{
title: '合规任务',
path: '/overManage',
index: '3-2',
icon: 'el-icon-setting',
children: []
},
{
title: '防火墙',
path: '/firewall',
index: '3-3',
icon: 'el-icon-film',
children: [
{
title: '防火墙规则监测',
path: '/firewallRuleMonitor',
index: '3-3-1',
icon: 'el-icon-set-up',
children: []
},
]
}
},
mounted() {},
created() {
this.setRouterList(this.menuList);
if(this.$route.path === '/riskControlCenter') {
this.init(this.$route.query.index);
}
},
watch: {
$route(v) {
if(v.path === '/riskControlCenter') {
this.init(this.$route.query.index);
}
}
},
methods: {
init(index) {
index = index ? index : '3-1';
this.setRouterList(this.menuList);
this.$router.push({
path: this.routerList[index],
query: {
...this.$route.query,
index: index,
actNav: this.$route.query.actNav
}
});
},
// 设置回调函数,取出树状数据中的所需数据,扁平化,减少后续循环
setRouterList(data) {
data.forEach(item => {
if(item.children.length === 0) {
this.routerList[item.index] = item.path;
} else {
this.setRouterList(item.children);
}
})
},
handleSelect(key) {
// console.log(key, keyPath, this.routerList[key]);
// 获取设置的路由地址
this.$router.push({
path: this.routerList[key],
query: {
index: key,
actNav: this.$route.query.actNav
}
});
}
}
}
script>
<style scoped lang="scss">
.riskControlCenter_light {
height: 100%;
display: flex;
justify-content: space-between;
/deep/ .el-menu {
background: #fff;
border: none;
.el-menu-item:not(.is-active), .el-submenu__title:not(.is-active) {
i {
color: #4389f9;
}
&:hover {
color: #4389f9;
background: rgba($color: #4389f9, $alpha: .3);
}
}
.el-menu-item.is-active {
color: #fff;
background: #4389f9;
}
}
.left {
width: auto;
height: 100%;
background: #fff;
position: relative;
.el-menu-vertical:not(.el-menu--collapse) {
min-width: 150px;
font-size: 14px;
font-weight: bold;
}
.btnGroup {
position: absolute;
z-index: 999;
width: 25px;
border-radius: 0 5px 5px 0;
padding: 14px 4px;
right: -25px;
top: 50%;
}
}
.right{
width: 100%;
overflow-y: auto;
background: #eef3ff;
}
}
.riskControlCenter {
height: 100%;
display: flex;
justify-content: space-between;
/deep/ .el-menu, .el-menu .el-menu--popup {
background: #1a3066;
border: none;
.el-menu-item, .el-submenu__title {
&:hover {
color: #fff;
background: #4389f9;
}
}
.el-menu-item.is-active, .el-submenu__title.is-active {
color: #fff;
background: #4389f9;
}
}
.left {
width: auto;
height: 100%;
background: #1a3066;
position: relative;
.el-menu-vertical:not(.el-menu--collapse) {
min-width: 150px;
font-size: 14px;
font-weight: bold;
}
.btnGroup {
position: absolute;
z-index: 999;
width: 25px;
border-radius: 0 5px 5px 0;
padding: 14px 4px;
right: -25px;
top: 50%;
}
}
.right{
width: 100%;
overflow-y: auto;
background: #05163d;
}
}
style>
案例较为粗浅,仅供参考! 其实可以再对其简化,使用循环嵌套,在Vue指令上,添加Js逻辑判断(三元运算),减少HTML结构庸余。
自定义导航栏收起后,鼠标悬浮提示栏样式
HTML代码
需要在所需自定义样式的下拉
中设置 popper-class
属性。
<el-submenu
:popper-class="$root.themeHomeChange === '1' ? 'submenu_diy_light' : 'submenu_diy'"
v-else
:index="item2.index"
:disabled="item2.disabled"
>...el-submenu>
CSS代码
< 了解 HTTP 这一篇就够了 :什么是 HTTP ?HTTP 和 HTTPS 有什么区别 ? >
< 每日小技巧:Vue常用修饰符 >
<Javascript技巧: Javascript 是个难泡的妞,学点技巧征服 “ 她 ” >
< 谈谈对 SPA(单页面应用)的理解 >