效果图:
知识点:
- Element-UI container容器组件
<el-container>
<el-header>Header</el-header>
<el-container>
/**侧边栏宽度200px**/
<el-aside width="200px">Aside</el-aside>
<el-main>Main</el-main>
</el-container>
</el-container>
container占满整个页面需要设置:height:100%;
header区域用display:flex布局
el-header{
display:flex;
/**两端对齐**/
justify-content:space-between;
/**垂直方向居中对齐**/
align-items:center;
>div{
display:flex:
align:center
}
}
- 侧边栏区域
只需要二级菜单:
<el-menu>
/**一级菜单**/
<el-submenu>
/**二级菜单**/
<el-menu-item></el-menu-item>
</el-submenu>
</el-menu>
background-color:侧边栏背景色
<el-submenu index="1">
/**一级菜单的目标区域**/
<template slot="title">
/**一级菜单的图标**/
<i class="el-icon-location"></i>
/**一级菜单内容**/
<span>导航一</span>
</template>
</el-submenu>
菜单的模板区域,可以给二级菜单页添加模板区域
- 菜单渲染:
在create
钩子函数中调用菜单栏内容,存储当前菜单的激活状态
create(){
this.getMenuList();
this.activePath=window.sessionStorage.getItem('activePath');
}
v-for循环输出列表信息,key绑定在返回的id上
一级菜单 v-for循环渲染
二级菜单v-for循环一级菜单的item
index属性菜单的唯一标识,字符串类型,需要将item.id数值转成字符串(item.id+’ ')
一级菜单的icon绑定到一级菜单的菜单id上,组成对象iconsObj,通过循环的id索引获取对应的图标。
对象访问属性的两种方法:
点
:obj.property
方括号
:obj[property],使用情况–变量访问属性
,或者是属性名师保留字、关键字、导致语法错误的字符(空格)
<el-submenu v-for="item in menulist" :key="item.id" :index="item.id+''">
<template slot="title">
<i :class=iconsObj[item.id]><i>
<span>{{item.authName}}</span>
</tempalte>
<el-menu-item v-for="subItem in item.childern" :key="subItem.id" :index="subItem.path" click="saveNavState('/'+subItem.path)">
<template slot="title">
<i class="el-icon-menu"></i>
<span>{{subItem.authName}}</span>
</template>
</el-menu-item>
</el-submenu>
iconsObj:{
'125': 'iconfont icon-users',
'103': 'iconfont icon-tijikongjian',
'101': 'iconfont icon-shangpin',
'102': 'iconfont icon-danju',
'145': 'iconfont icon-baobiao'
}
default-active属性
:当前激活菜单的index
router属性
:菜单激活,将index作为path进行路由导航
unique-opened属性
:只保持一个菜单栏展开
collapse-transition属性
:是否开启折叠动画
<el-menu
:collapse="isCollapse"
:collapse-transition="false"
background-color="#545c64"
text-color="#fff"
active-text-color="#409bff"
unique-opened
router
//绑定在data上的activePath上,可以使用$route.path直接获取当前连接的path 就不用再绑定事件了
:default-active="activePath"
>
</el-menu>
data(){
return {
activePath:'',
}
},
methods:{
saveNavState(activePath){
//将激活的菜单状态保存在本地
window.sessionStorage.setItem('activePath',activePath);
//将当前的点击的submenu,传给default-active属性
this.activePath=activePath;
}
}
绑定侧边栏的宽度width,三元运算符判断,当折叠的时候(isCollapse:true),侧边栏宽度64px,当正常显示的时候(isCollapse:false),侧边栏宽度200px
<el-aside :width="isCollapse ? '64px' : '200px'">
<!--当点击按钮的时候触发事件toggleCollapse(),切换控制器isCollapse-->
<div class="toggle-button" @click="toggleCollapse">|||</div>
<el-menu
:collapse="isCollapse"
:collapse-transition="false"
background-color="#545c64"
text-color="#fff"
active-text-color="#409bff"
unique-opened
router
:default-active="activePath"
>
<!-- <el-menu :collapse="isCollapse" :collapse-transition="false" background-color="#545c64" text-color="#fff" active-text-color="#409bff" unique-opened router :default-active="this.$route.path"> -->
<!--激活的文本色-->
<!--一级菜单-->
<!--给index绑定动态值 不然点一个其他都关闭了 只接受字符串 下面是未修改之前的-->
<!-- <el-submenu index="1" v-for="item in menulist" :key="item.id"> -->
<el-submenu
:index="item.id + ''"
v-for="item in menulist"
:key="item.id"
>
<template slot="title">
<!--图标显示-->
<i :class="iconsObj[item.id]"></i>
<!--一级菜单标题-->
<span>{{ item.authName }}</span>
</template>
<!--二级菜单-->
<el-menu-item
:index="'/' + subItem.path"
v-for="subItem in item.children"
:key="subItem.id"
@click="saveNavState('/' + subItem.path)"
>
<template slot="title">
<!--图标显示-->
<i class="el-icon-menu"></i>
<!--一级菜单标题-->
<span>{{ subItem.authName }}</span>
</template>
</el-menu-item>
</el-submenu>
</el-menu>
</el-aside>
- 点击按钮,折叠菜单栏
el-menu组件的collapse属性
布尔值,绑定到一个控制器。当点击页面上方按钮,切换布尔值,控制菜单的折叠和展开。
//结构区域
<button @click="toggleCollapse">|||</button>
<el-menu :collaspe="isCollapse">
</el-menu>
//行为区域
data(){
return {
//初始化的时候,菜单显示是展开的
isCollapse:fasle,
}
}
methods:{
toggleCollapse(){
//点击按钮的时候,切换isCollapse的布尔值
this.isCollapse=!this.isCollapse;
}
}
5 . 点击退出按钮
- 清空token
- 路由导航到指定的页面
methods:{
//退出
logout(){
//清空本地会话存储内容,在刷新页面的时候,还能够定位到激活的路径上
window.sessionStorgae.clear();
//路由导航到指定页面
this.$router.push('/login')
}
}
注
:router
和route
的区别:
router统管所有的路由内容,route只包含当前的路由内容,可以获取params
this.$router
访问路由器
this.$route
访问当前路由
- 路由重定向
路径匹配到/home的时候,显示Welcome组件
const router=new Router({
routes:[
{path:'/login',component:Login},
{path:'/home',redirect:'/welcome',component:Home},
]
})
export default router
- 中间区域
设置router-view
占位,菜单切换,显示不同菜单内容。
<el-main>
<router-view/>
</el-main>
- axios
项目引入axios
安装:npm install axios --save
在main.js引入
import axios from 'axios'
//将axios添加到Vue的原型对象$http属性上
Vue.prototype.$http=axios;
axios拦截
请求拦截
axios.interceptors.request.use(function(request){
//成功执行
},function(error){
//失败执行
})
登录的时候,请求头添加Authorization属性
axios.interceptors.request.use(config->{
//在请求头中添加Authorization字段,将config返回
config.headers.Authorization=window.sessionStorage.getItem('token');
//在最
return config
})
响应拦截
axios.interceptors.response.use(function(request){
//成功执行
},function(error){
//失败执行
})
其中:回调函数,返回回调函数参数
参考:https://www.runoob.com/vue2/vuejs-ajax-axios.html