目录
前言
在后台系统设计中,经常会使用layout布局以及路由,想知道具体怎么使用,继续往下看看吧~
首先我们来看一下效果图:
上面的效果图主要有三部分组成:头部、侧边导航、主要内容区域。当我们点击页面时,切换主要内容区域,所以需要使用layout布局。侧边导航又有子菜单,所以我们需要路由嵌套。分析完了,那我们开始吧~
首先我们要在src文件夹下面,新建一下文件夹和文件:
一、layout布局
1.创建头部(header.vue)
头部如下图:
思路:分为左边的名称,右边的登录名称和注销图标,这种左右布局肯定要使用flex布局啦~;进入首页后我们要使用localStorage把登陆时存储的用户名取出来显示在右边登录名的地方,当用户点击注销图标的时候,清除localStorage,并跳转回登陆页面。下面直接上代码:
<template>
<div class="header_container ">
<div class="logo white_color">
<span>XXX后台管理系统</span>
</div>
<div class="user_info white_color">
<span @click="outLogin"> <i class="el-icon-warning-outline"
style="margin-right: 15px"></i></span>
<span>{{user}}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
user: ''
}
},
mounted() {
this.info()
},
methods: {
info() {
var account = JSON.parse(localStorage.getItem('token'))
console.log(account, 'account')
this.user = account.account
},
outLogin() {
this.user = ''
localStorage.removeItem('token')
this.$router.push('/login')
}
}
}
</script>
<style lang='scss'>
</style>
此处的css我写在了公共样式文件里面,你需要,在src下创建一下文件夹以及文件:
然后在public.scss中输入以下内容:
$mian_color: rgb(179, 162, 199);
$weightMain_color:rgb(96, 74, 123);
$contrast_color:white;
.mian_color{
color: $mian_color;
}
.white_color{
color:$contrast_color
}
body{
margin: 0;
}
.header_container {
position: flex;
top: 0;
left: 0;
width: 100%;
background: $mian_color;
font-size: 12px;
display: flex;
justify-content: space-between;
.logo {
font-size: 24px;
font-weight: 600px;
}
}
.el-header {
background-color:$mian_color !important;
color: #333;
line-height: 60px;
}
.el-aside {
height: calc(100vh - 60px) !important;
background: $weightMain_color;
}
.el-menu {
border-right:0 !important
}
然后在App.vue中引入这两个样式,输入以下代码:
<style lang='scss'>
@import './styles/public.scss';
@import './styles/index.scss';
</style>
2.创建侧边导航(sliber.vue)
侧边导航如下图:
思路:样式就是elmentUI的侧边导航。重点是树状菜单的组合,后端返回的肯定是数组中包裹对象,所以我们需要根据其中的pid判断是哪一个一级菜单的子集。下面直接上代码:
<template>
<div class="asideNav">
<el-menu :default-active="$route.path"
class="el-menu-vertical"
router
unique-opened
:collapse="iscollapse"
:collapse-transition="false"
active-text-color='#FFC000'
background-color="#604A7B"
text-color="#fff">
<div v-for="(item,i) in lastMeun"
:key="i">
<el-submenu :index="item.prouter"
v-if="item.children">
<template slot="title">
<i :class="item.icon"></i>
<span class="tohide">{{item.name}}</span>
</template>
<el-menu-item :index="val.crouter"
v-for="val in item.children"
:key="val.id">
<i class="el-icon-s-help"></i>
<span>{{val.name}}</span>
</el-menu-item>
</el-submenu>
<el-menu-item :index="item.prouter"
v-else>
<i :class="item.icon"></i>
<span slot="title">{{item.name}}</span>
</el-menu-item>
</div>
</el-menu>
</div>
</template>
<script>
export default {
data() {
return {
defaultActive: '/home',
iscollapse: false,
logourl: require('../../assets/logo.png'),
username: null,
show: false,
lastMeun: [],
pMeun: [],
cMeun: [],
meunList: [
{ id: '1', pid: '', name: '首页', router: '/home', icon: 'el-icon-eleme' },
{ id: '2', pid: '', name: '列表管理', router: '/list', icon: 'el-icon-s-tools' },
{ id: '3', pid: '', name: '产品管理', router: '/proudct', icon: 'el-icon-star-on' },
{ id: '4', pid: '', name: '长度管理', router: '/length', icon: 'el-icon-edit' },
{ id: '5', pid: '3', name: '产品管理one', router: '/proudct/one', icon: 'el-icon-edit' },
{ id: '6', pid: '3', name: '产品管理two', router: '/proudct/two', icon: 'el-icon-edit' },
{
id: '7',
pid: '3',
name: '产品管理three',
router: '/proudct/three',
icon: 'el-icon-edit'
},
{ id: '8', pid: '3', name: '产品管理four', router: '/proudct/four', icon: 'el-icon-edit' },
{ id: '9', pid: '', name: '双数管理', router: '/double', icon: 'el-icon-bell' },
{ id: '10', pid: '', name: '数据管理', router: '/data', icon: 'el-icon-info' },
{ id: '11', pid: '10', name: '数据管理one', router: '/data/one', icon: 'el-icon-edit' },
{ id: '12', pid: '10', name: '数据管理two', router: '/data/two', icon: 'el-icon-edit' }
]
}
},
mounted() {
this.info()
},
methods: {
info() {
var pMeun = [] //父级菜单
var cMeun = [] //子菜单
if (this.meunList.length > 0) {
//有数据则进行下一步
//遍历菜单列表,如果没有pid(父级id,没有表示他是一级菜单),则放进pMeun,有则放进cMeun
this.meunList.forEach((item) => {
if (!item.pid) {
pMeun.push({
id: item.id,
name: item.name,
icon: item.icon,
prouter: item.router,
// meta: { title: i.name, icon: i.icon, access: 1 },
children: []
})
} else {
cMeun.push(item)
}
})
console.log(pMeun, cMeun)
//判断pMeun和cMeun中id和pid是否相等,相等则将该项加入对应pMeun的children中
pMeun.forEach((pitem) => {
cMeun.forEach((citem) => {
if (citem.pid == pitem.id) {
// console.log(pitem, '11')
pitem.children.push({
id: citem.id,
name: citem.name,
crouter: citem.router
// meta: { title: i.name, icon: i.icon, access: 1 },
})
}
})
})
//如果pMeun中的children没有数据的,则删除该children属性
pMeun.forEach((item, index) => {
if (!item.children.length) {
delete pMeun[index].children
}
})
console.log(pMeun, 'pMeun')
this.lastMeun = pMeun //赋值给菜单数据源
} else {
retrun
}
},
setcollapse() {
this.iscollapse = !this.iscollapse
this.$nextTick(() => {
if (this.iscollapse) {
$('#logo').css('width', '64px')
$('.el-aside').css('width', 'auto')
$('.tohide,.el-submenu__title .el-icon-arrow-right').css('display', 'none')
} else {
$('#logo').css('width', 'auto')
$('.el-aside').css('width', '152px')
$('.tohide,.el-submenu__title .el-icon-arrow-right').css('display', 'inline')
}
})
}
}
}
</script>
<style lang='scss' scoped>
.asideNav {
text-align: left;
}
</style>
最后,要在layout文件夹下面的index.vue写下嵌套的结构,代码如下:
<template>
<el-container class="contanier_box">
<!-- 头部 -->
<el-header>
<Header></Header>
</el-header>
<!-- 头部下面的内容 -->
<el-container>
<!-- 侧边导航 -->
<el-aside width='205px'
class="sliber_box">
<Sliber></Sliber>
</el-aside>
<!-- 主要内容 -->
<el-main>
<router-view></router-view>
</el-main>
</el-container>
</el-container>
</template>
<script>
import Sliber from './components/sliber.vue'
import Header from './components/header.vue'
export default {
components: {
Sliber,
Header
}
}
</script>
<style lang="scss" scoped>
</style>
二、路由嵌套
1.配置layout和路由
打开router文件夹下面的index.js,引入layout,如下图:
index文件完整代码如下:
import Vue from 'vue'
import Router from 'vue-router'
// 引入自己写的layout
import Layout from '@/layout'
Vue.use(Router)
export default new Router({
routes: [
{
path: '/',//根目录路由为/
component: Layout,//指定使用Layout组件布局
redirect: '/home',//重定向至/home页面
children: [{//子菜单信息
path: '/home',//路径
name: 'home',
component: () => import('@/views/home'),//指定组件
meta: { title: '首页', access: 0, affix: true }
}]
},
{
path: '/login',
name: 'login',
component: () => import('@/views/login')
},
{
path: '/list',
component: Layout,
children: [{
path: "/list",
name: 'list',
component: () => import('@/views/list'),
meta: { title: 'list管理', access: 0 }
}]
},
{
path: '/length',
component: Layout,
children: [{
path: "/length",
name: 'length',
component: () => import('@/views/length'),
meta: { title: 'length管理', access: 0 }
}]
},
{
path: '/double',
component: Layout,
children: [{
path: "/double",
name: 'double',
component: () => import('@/views/double'),
meta: { title: 'double管理', access: 0 }
}]
},
{
path: '/proudct',
component: Layout,
redirect: '/proudct/one',
meta: { title: '产品管理' },
children: [{
path: '/proudct/one',
name: 'proudct_one',
component: () => import('@/views/proudct/one'),
meta: { title: '产品管理1', access: 0, affix: true }
},
{
path: '/proudct/two',
name: 'proudct_two',
component: () => import('@/views/proudct/two'),
meta: { title: '产品管理2', access: 0, affix: true }
},
{
path: '/proudct/three',
name: 'proudct_three',
component: () => import('@/views/proudct/three'),
meta: { title: '产品管理3', access: 0, affix: true }
},
{
path: '/proudct/four',
name: 'proudct_four',
component: () => import('@/views/proudct/four'),
meta: { title: '产品管理4', access: 0, affix: true }
}]
},
{
path: '/data',
component: Layout,
redirect: '/data/one',
meta: { title: '数据管理' },
children: [{
path: '/data/one',
name: 'data_one',
component: () => import('@/views/data/one'),
meta: { title: '数据管理1', access: 0, affix: true }
},
{
path: '/data/two',
name: 'data_two',
component: () => import('@/views/data/two'),
meta: { title: '数据管理2', access: 0, affix: true }
}]
},
]
})
注意:当然,路由中涉及的页面也要像创建首页一样创建好,否则不能运行成功哟
总结
以上就是今天要讲的内容,本文代码量大,但其实知识点就只有两个:路由嵌套和layout布局,千万不要被代码吓到了哟~。
如果你只想搭建项目得框架,那么走到这一步就已经成功了哟,接下里得几章是扩展功能得~
上一章:vue+elementUI后台系统(第五章:权限设置)
下一章:vue+elementUI后台系统(第七章:路由重定向)