赞
踩
首先在elementui官网Container布局容器中找到一个布局相似的布局,复制其代码至Home.vue并给各区域加上背景颜色如下
<template> <el-container class="home-container"> <!-- 头部区域 --> <el-header>Header<el-button type="info" @click="logout">退出</el-button></el-header> <!-- 页面主体区域 --> <el-container> <!-- 侧边栏 --> <el-aside width="200px">Aside</el-aside> <!-- 右侧内容主体 --> <el-main>Main</el-main> </el-container> </el-container> </template>
.el-header { background-color: #373D41; } .el-aside { background-color: #333744; } .el-main { background-color: #eaedf1; }
最终呈现aside和main没有铺满全屏,F12检查元素发现
上面的#app可以铺满全屏,但是下面的el-container不能铺满全屏(显然这个是最外层的el-container)
所以我们需要给el-container加一个height :100%让它铺满全屏
但是,这里有两个el-container标签,所以给标签加一个class
<el-container class="home-container">
<style lang="less" scoped> .home-container { height: 100%; }
最后呈现结果如下:
布局之前的样子and布局之后的样子
<!-- 头部区域 --> <el-header> <div> <img src="../assets/heima.png" alt=""> <span>电商后台管理系统</span> </div> <el-button type="info" @click="logout">退出</el- button> </el-header>
.el-header { background-color: #373D41; //下面两句,把子元素靠边对齐平均分剩余的空间 display: flex; justify-content: space-between; //因为header本身自带内边距,让图片居左对齐 padding-left: 0; align-items: center;//按钮纵向居中 color: #fff;//设置文字颜色 font-size: 20px;//文字大小 > div {//这里写不写>都可以 display: flex; align-items: center;//纵向居中 } span { margin-left: 15px;//让文字和图片之间有一定距离 } }
css样式中的>号
body>div。>是子代选择符,它表示的是选择body的子代div。
例如在结构
<body> <div id="我被选择" class="1"> <div class="2">我没有被选择</div> </div> </body>
body>div 只能选择class="1"的div,因为它是body的子代。而class="2"的div没有被选择。
查elementUI文档NavMenu 导航菜单
找到侧栏,把自定义颜色的那部分代码复制到el-aside中
<!-- 侧边栏 --> <el-aside width="200px"> <!-- 侧边栏菜单区域 --> <el-menu background-color="#545c64" text-color="#fff"//这里前面删除了一些用不到的属性 active-text-color="#ffd04b"> <el-submenu index="1"> <template slot="title"> <i class="el-icon-location"></i> <span>导航一</span> </template> <el-menu-item-group> <template slot="title">分组一</template> <el-menu-item index="1-1">选项1</el-menu- item> <el-menu-item index="1-2">选项2</el-menu- item> </el-menu-item-group> <el-menu-item-group title="分组2"> <el-menu-item index="1-3">选项3</el-menu- item> </el-menu-item-group> <el-submenu index="1-4"> <template slot="title">选项4</template> <el-menu-item index="1-4-1">选项1</el- menu-item> </el-submenu> </el-submenu> <el-menu-item index="2"> <i class="el-icon-menu"></i> <span slot="title">导航二</span> </el-menu-item> <el-menu-item index="3" disabled> <i class="el-icon-document"></i> <span slot="title">导航三</span> </el-menu-item> <el-menu-item index="4"> <i class="el-icon-setting"></i> <span slot="title">导航四</span> </el-menu-item> </el-menu> </el-aside>
下面进行进一步美化:
①侧边栏和侧栏背景保持一致,颜色统一
<!-- 侧边栏菜单区域 --> <el-menu background-color="#333744"
②这里只会用到一级二级菜单栏,多余的删除(导航234均删除)
导航一中的分组不会用到,均删除
删完长这样,然后只会用到二级菜单,将三级菜单选项4选项1删除
使用选项一的代码复制到一级菜单submenu中,并给它添加图标文本
最终代码
<!-- 侧边栏 --> <el-aside width="200px"> <!-- 侧边栏菜单区域 --> <el-menu background-color="#333744" text-color="#fff" active-text-color="#ffd04b"> <!-- 一级菜单 --> <el-submenu index="1"> <!-- 一级菜单模板区域 --> <template slot="title"> <!-- 图标 --> <i class="el-icon-location"></i> <!-- 文本 --> <span>导航一</span> </template> <!-- 二级菜单 --> <el-menu-item index="1-4-1"> <!-- 二级菜单模板区域 --> <template slot="title"> <!-- 图标 --> <i class="el-icon-location"></i> <!-- 文本 --> <span>导航二</span> </template> </el-menu-item> </el-submenu> </el-menu> </el-aside>
最终展示如下:
需要授权的API(除了登录接口都需要授权),必须在请求头部使用Authorization字段提供的token令牌,否则无法正常获取数据
通过axios请求拦截器添加token,保证拥有获取数据的权限。
axios的interceptors属性中有一个request请求拦截器,使用use函数为请求拦截器挂载一个回调函数。只要通过axios向服务器端发了一次请求,必然会在发送请求期间优先调用use回调函数对请求做一下预处理,回调函数中return config表示把请求头做了一次预处理,请求经过处理之后才会被发送到服务器
main.js中配置
// 配置请求的根路径 axios.defaults.baseURL = 'https://lianghj.top:8888/api/private/v1/' axios.interceptors.request.use(config => { console.log(config) // 在最后必须return config return config }) Vue.prototype.$http = axios
返回登录页面点击登录打印输出config
可以发现有headers,我们需要在headers中挂载一个Authorization
axios.defaults.baseURL = 'https://lianghj.top:8888/api/private/v1/' axios.interceptors.request.use(config => { config.headers.Authorization = window.sessionStorage.getItem('token') // 在最后必须return config return config }) Vue.prototype.$http = axios
查阅文档
获取左侧菜单数据使用get,路径是menus
this.$http.get('munus')
home.vue中这样写:
created () { this.getMenuList() },
// 获取所有菜单 async getMenuList () { const { data: res } = await this.$http.get('menus') console.log(res) }
使用async和await使其只获取data并把data赋值给res并打印输出
将获取到的数据挂载到data中
data () { return { // 左侧菜单数据 menulist: [] } },
async getMenuList () { const { data: res } = await this.$http.get('menus') if (res.meta.status !== 200) return this.$message.error(res.meta.msg) this.menulist = res.data console.log(res) }
若不等于200表示为获取成功输出提示信息,否则就是获取成功将res.data数组的值赋值给menulist
一级菜单栏
①menuList是一个数组,可以直接使用for循环渲染到菜单栏
<!-- 一级菜单 --> <el-submenu index="1" v-for="item in menulist" :key="item.id">
②一共是5个一级菜单栏,但是可以发现此菜单栏是同时展开五个,我们需要点开一个就只展开一个。原因分析:index只有一个都为1,所以我们需要给它们指定5个不同的index,可以发现id是唯一的,可以使用id做index。
但是直接index=“item.id”又会报错
index只能接收string类型不能是number
所以我们写成这样:index=“item.id+' '”(string+任何类型都是string)
③如下图所示:
我们可以发现data数组authName每个都不一样应该是一级导航栏的名称,children是二级导航栏
使用{{item.authName}}将名称渲染到导航栏
二级菜单栏
如上图所示:children是二级导航栏
每一个data数据里面都有一个children
完整代码
<!-- 一级菜单 --> <el-submenu :index="item.id+''" v-for="item in menulist" :key="item.id"> <!-- 一级菜单模板区域 --> <template slot="title"> <!-- 图标 --> <i class="el-icon-location"></i> <!-- 文本 --> <span>{{item.authName}}</span> </template> <!-- 二级菜单 --> <el-menu-item :index="subItem.id+''" v-for="subItem in item.children" :key="subItem.id"> <!-- 二级菜单模板区域 --> <template slot="title"> <!-- 图标 --> <i class="el-icon-location"></i> <!-- 文本 --> <span>{{subItem.authName}}</span> </template> </el-menu-item> </el-submenu>
①更换二级菜单栏点击时的文本颜色active-text-color
<!-- 侧边栏菜单区域 --> <el-menu background-color="#333744" text-color="#fff" active-text-color="#409EFF">
②更换二级菜单栏图标-----elementui官网icon图标,找到
<!-- 二级菜单模板区域 --> <template slot="title"> <!-- 图标 --> <i class="el-icon-menu"></i>
自定义图标
③更改一级菜单栏(每个菜单栏的图标都不一样)
icon图标需要使用之前从素材文件夹copy到assets文件夹的fonts文件夹,里面有个demo_fontclass.html右击选第一个open with live server打开
上面有相应图标而且还有使用规则
man.js已经导入此文件,可以直接使用
<!-- 一级菜单模板区域 --> <template slot="title"> <!-- 图标 --> <i :class="iconsObj[item.id]"></i>
data () { return { // 左侧菜单数据 menulist: [], iconsObj: { 125: 'iconfont icon-user', 103: 'iconfont icon-tijikongjian', 101: 'iconfont icon-shangpin', 102: 'iconfont icon-danju', 145: 'iconfont icon-baobiao' } }
自定义图标数组iconsobj,通过对应id查找对应icon图标。id从控制台打印出来的data数组里面找的。这个:class是v-bind:class的缩写,必须带:
④让一级菜单图标和文本之间有一定距离
.iconfont { margin-right: 10px; }
直接在最下边写的css样式,也没有定义class类,应该是因为进入icon图标时:class=“iconfont icon-xxx”前面都是iconfont开头的
①实现展开二级菜单只能展开一个,打开了这个,另一个就自动关上
打开elementUI文档,NavMenu导航菜单最下面Menu Attribute中有一个
unique-opened | 是否只保持一个子菜单的展开 | boolean | — | false |
---|---|---|---|---|
默认是false,把它设为true即可
这个属性属于Menu,就加到el-menu标签中
有两种写法,直接写unique-opened或者:unique-opened=“true”,使用第二种写法的时候必须加上:表示属性绑定,否则不生效。
②优化二级菜单栏边框对齐
检查发现el-menu自带一个border边框,去掉边框就可以实现对齐
.el-aside { background-color: #333744; .el-menu { border-right: none; } }
侧边栏的css样式中嵌套一个el-menu的样式,对齐效果如下:
①样式:
侧边栏aside下面定义一个div,并定义一个点击事件,|||这个是点击按钮
<!-- 侧边栏 --> <el-aside width="200px"> <div class="toggle-button" @click="toggleCollapse">|||</div>
css定义一下样式;
.toggle-button { background-color: #4a5064; font-size: 10px; line-height: 24px; color: #fff;//按钮颜色 text-align: center; letter-spacing: 0.2em;//设置|之间的间距(字符间距) cursor: pointer;//鼠标移过去变为小手 }
②实现功能:
elementui中NavMenu最下面有一个属性
collapse | 是否水平折叠收起菜单(仅在 mode 为 vertical 时可用) | boolean | — | false |
---|---|---|---|---|
collapse-transition | 是否开启折叠动画 | boolean | — | true |
collapse置为false表示不折叠,true表示折叠
collapse-transition默认为true,表示默认启用了折叠动画,但是这个动画不好看,我们将它置为false
这里既然有一个这个属性,我们就利用它实现展开和折叠,点击一下展开,再点击一下折叠,方法就是让当前collapse的值取反就可以了。我们首先在data中定义一个动态改变的值isCollapse,让它刚开始是false就是不折叠,点击事件给他取反,让collapse属性等于isCollapse
<el-menu :collapse="isCollapse" :collapse-transition="false">
data () { return { // 是否折叠 isCollapse: false } },
// 点击按钮,切换菜单的折叠与展开 toggleCollapse () { // 点击时取反 this.isCollapse = !this.isCollapse }
折叠效果如下:
③实现折叠时侧边栏宽度变小
<!-- 侧边栏 --> <el-aside :width="isCollapse ? '64px':'200px'">
当isCollapse等于true(折叠)时,宽度为64px;
当isCollapse等于false(不折叠)时,宽度为200px;
折叠效果如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。