实现的功能
功能 | 详述 |
---|---|
首页整体布局 | |
侧边栏 | 获取和渲染左侧菜单数据;菜单折叠和展开;侧边栏路由;激活高亮 |
主体 | 嵌套显示子组件 |
axios拦截器添加token验证 | axios请求拦截,headers.Authorization |
使用到的Element-ui组件
组件名称_EN | 注册 | 备注 |
---|---|---|
Container | Vue.use(Container) | 布局容器 |
Header | Vue.use(Header) | |
Aside | Vue.use(Aside) | |
Main | Vue.use(Main) | |
Menu | Vue.use(Menu) | 导航菜单 |
Submenu | Vue.use(Submenu) | |
MenuItem | Vue.use(MenuItem) |
主页
1、渲染组件和路由
2、布局
主体布局
<el-container>
<el-header>Header</el-header>
<el-container>
<el-aside width="200px">Aside</el-aside>
<el-main>Main</el-main>
</el-container>
</el-container>
侧边栏:二级菜单+图标和文本
3、axios拦截器添加token验证
// [main.js]
// axios请求拦截
axios.interceptors.request.use(config => {
// 为请求头对象,添加Token 验证的 Authorization字段
config.headers.Authorization = window.sessionStorage.getItem('token')
return config
})
4、获取渲染左侧菜单数据
①获取左侧菜单数据
// [Home.vue -> data]
menulist: []
// [Home.vue -> created]
created() {
this.getMenuList()
// ......
}
// [Home.vue -> methods]
methods: {
async getMenuList() {
const { data: res } = await this.$http.get('menus')
if (res.meta.status !== 200) return this.$message.err(res.meta.msg)
this.menulist = res.data
}
}
②渲染左侧菜单数据
v-for:双重循环渲染一级/二级菜单项
:key:指定key
index:为每一个submenu指定唯一index
unique-opened :每次只展开一个菜单项
图标:数组
<!-- [Home.vue] -->
<el-menu background-color="#333744" text-color="#fff" active-text-color="#409BFF" unique-opened >
<!-- 一级菜单 -->
<el-submenu :index="item.id+''" :key="item.id" v-for="item in menulist">
<!-- 一级菜单模板区域 -->
<template slot="title">
<i :class="iconsObj[item.id]"></i>
<span>{{item.authName}}</span>
</template>
<!-- 二级菜单 -->
<el-menu-item :index="'/'+subItem.path+''" :key="subItem.id" v-for="subItem in item.children">
<!-- 二级菜单模板区域 -->
<template slot="title">
<i class="el-icon-menu"></i>
<span>{{subItem.authName}}</span>
</template>
</el-menu-item>
</el-submenu>
</el-menu>
- 显示图标
// [Home.vue -> data]
iconsObj: {
'125': 'iconfont icon-user',
'103': 'iconfont icon-tijikongjian',
'101': 'iconfont icon-shangpin',
'102': 'iconfont icon-danju',
'145': 'iconfont icon-baobiao',
}
- 右侧边框线对不齐
.el-menu {
border-right: none;
}
③点击按钮,切换菜单折叠和展开
:collapse="isCollapse" 是否水平折叠收起菜单
:collapse-transition="false" 动画过渡更流畅
<!-- [Home.vue] -->
<div class="toggle-button" @click="toggleCollapse">|||</div>
<!-- 折叠宽度 -->
<el-aside :width="isCollapse ? '64px' : '200px'">
// [Home.vue -> data]
// 是否折叠
isCollapse: true
// [Home.vue -> methods]
// 点击按钮,切换菜单折叠和展开
toggleCollapse() {
this.isCollapse = !this.isCollapse
}
④嵌套显示子组件
- 引入
// [main.js]
import Welcome from '../components/Welcome.vue'
- 配置路由规则
// [main.js]
const routes = [
// ......
{
path: '/home', component: Home, redirect: '/welcome', children: [
{ path: '/welcome', component: Welcome }
]
}
// ......
]
- 路由占位符
<!-- [Home.vue] -->
<!-- 右侧内容主题 -->
<el-main>
<!-- welcome路由占位符 -->
<router-view></router-view>
</el-main>
⑤侧边栏路由
router:开启路由
index:修改跳转的url
<!-- [Home.vue] -->
<el-menu router></el-menu>
<el-menu-item :index="'/'+subItem.path+''" ></el-menu-item>
⑥激活高亮
:default-active="activePath" 当前激活菜单的index
<!-- [Home.vue] -->
<el-menu :default-active="activePath">
<!-- 二级菜单 -->
<el-menu-item @click="saveNavState('/' + subItem.path)">
// [Home.vue -> data]
// 被激活的链接地址
activePath:''
// [Home.vue -> created]
created() {
// ......
this.activePath = window.sessionStorage.getItem('active')
}
// [Home.vue -> methods]
// 保存链接的激活状态
saveNavState(activePath){
window.sessionStorage.setItem('active',activePath);
this.activePath = activePath
}