第三节:基础组件(Container布局、NavMenu导航) 之 系统主页面搭建
一. 基础组件
1. Container布局
(1). 我们采用如下图的布局形式,代码如下
代码分享:
<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>
2. NavMenu导航菜单
目标:左侧菜单栏,可以自定义收缩和展开,自定义图标,这里只设计二级菜单。
(1).展开or收缩
给<el-menu>标签添加添加属性 :collapse="isCollapse",值为true展开,false为关闭。
(2).相关颜色的设置
给<el-menu>标签添加下面属性
(3). 只保持一个子菜单展开
给<el-menu>添加unique-opened属性,设置为true,表示只有一个菜单展开,也可以在<el-menu>上直接写这个标签,等价于设置为true。
(4). 启用vue-route模式
PS:也就是说在index属性中,存放路径,就可以进行跳转。后面的@click事件,与跳转无关。
(5). 如何设置默认展开项目
通过default-active属性来设置,取值index属性中的值,赋值为哪个index属性中的值,哪个index所在的标签就会被选中。
(6). 如何记录当前页面(重点)
目标1:每次登录的时候,固定展开一个一级菜单。比如每次打开的时候,我都想展开的是权限管理。
思路:通过default-openeds设置默认登录展开的一级菜单的index值。如下图,103就是权限管理对应的index值。
目标2:比如我现在在【用户管理】页面,刷新了一下浏览器,还是进入到【用户管理】页面,而不是其他的默认页面。
思路: 给每个二级菜单添加一个点击事件,记录当前index值,赋值给activePath,并存放到缓存中,系统刷新时,自动从缓存中加载该值,如果没有值,则默认什么标签也不打开。
补充:简介写法,一句话搞定, $route.path直接能拿到点击的path
:default-active="$route.path"
(7). 接口数据
{
"data": [{
"id": 125,
"authName": "用户管理",
"path": "users",
"children": [{
"id": 110,
"authName": "用户列表",
"path": "users",
"children": [],
"order": null
}],
"order": 1
}, {
"id": 103,
"authName": "权限管理",
"path": "rights",
"children": [{
"id": 111,
"authName": "角色列表",
"path": "roles",
"children": [],
"order": null
}, {
"id": 112,
"authName": "权限列表",
"path": "rights",
"children": [],
"order": null
}],
"order": 2
}, {
"id": 101,
"authName": "商品管理",
"path": "goods",
"children": [{
"id": 104,
"authName": "商品列表",
"path": "goods",
"children": [],
"order": 1
}, {
"id": 115,
"authName": "分类参数",
"path": "params",
"children": [],
"order": 2
}, {
"id": 121,
"authName": "商品分类",
"path": "categories",
"children": [],
"order": 3
}],
"order": 3
}, {
"id": 102,
"authName": "订单管理",
"path": "orders",
"children": [{
"id": 107,
"authName": "订单列表",
"path": "orders",
"children": [],
"order": null
}],
"order": 4
}, {
"id": 145,
"authName": "数据统计",
"path": "reports",
"children": [{
"id": 146,
"authName": "数据报表",
"path": "reports",
"children": [],
"order": null
}],
"order": 5
}],
"meta": {
"msg": "获取菜单列表成功",
"status": 200
}
}
二. 系统主页面
1. 页面效果
2. 代码分享
<template> <el-container class="home-container"> <!-- 头部区域 --> <el-header> <div> <img src="../assets/heima.png" alt=""> <span>后台管理系统</span> </div> <el-button type="info" @click="logout" size="small">退出</el-button> </el-header> <!-- 页面主体区域 --> <el-container> <!-- 侧边栏 --> <el-aside :width="isCollapse ? '64px' : '200px'"> <div class="toggle-button" @click="toggleCollapse">|||</div> <!-- 侧边栏菜单区域 --> <el-menu background-color="#333744" text-color="#fff" active-text-color="#409EFF" :collapse="isCollapse" :collapse-transition="false" :default-active="activePath" router unique-opened> <!-- 一级菜单 --> <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-main> <!-- 路由占位符 --> <router-view></router-view> </el-main> </el-container> </el-container> </template> <script> export default { data() { return { // 左侧菜单数据 menulist: [], // 图标 iconsObj: { 125: 'iconfont icon-user', 103: 'iconfont icon-tijikongjian', 101: 'iconfont icon-shangpin', 102: 'iconfont icon-danju', 145: 'iconfont icon-baobiao' }, // 是否折叠 isCollapse: false, // 被激活的链接地址(解决二级菜单点击高亮问题) activePath: '' } }, // 实例创建之后执行 created() { // 1.获取左侧所有菜单 this.getMenuList() this.activePath = window.sessionStorage.getItem('activePath') }, methods: { // 1.退出 logout() { window.sessionStorage.clear() this.$router.push('/login') }, // 2.获取左侧所有菜单 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) }, // 3. 切换左侧菜单的折叠与展开 toggleCollapse() { this.isCollapse = !this.isCollapse }, // 4.保存当前页面的选中状态 // (比如刷新了一下浏览器,还是进入到刷新前的页面,而不是默认打开页面) saveNavState(activePath) { window.sessionStorage.setItem('activePath', activePath) this.activePath = activePath } } } </script> <style lang="less" scoped> .home-container { height: 100%; } .el-header { background-color: #373d41; display: flex; justify-content: space-between; padding-left: 0; align-items: center; color: #fff; font-size: 20px; >div { display: flex; align-items: center; span { margin-left: 15px; } } } .el-aside { background-color: #333744; .el-menu { border-right: none; } } .el-main { background-color: #eaedf1; } .iconfont { margin-right: 10px; } .toggle-button { background-color: #4a5064; font-size: 10px; line-height: 24px; color: #fff; text-align: center; letter-spacing: 0.2em; cursor: pointer; } </style>
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。