Element-UI+Vue实现主页布局——侧边栏用户布局(上)
第一节文章:
Element-UI+vue实现登录表单_我爱布朗熊的博客-CSDN博客
第二节文章:
Vue+ELementUI主页布局----侧边栏布局(el-aside)_我爱布朗熊的博客-CSDN博客
目录
一、实现首页路由的重定向
我么重现添加一个WelCome组件,以子路由的形式存在于home这个规则中(就是在主页面中的子路由)
首先定义一个二级路由:
const router =new VueRouter({
routes:[
{
// 如果路径是斜线,那我们就把他对应到/login上
path:'/',
// 重定向
redirect:'/login'
},
// 第一个路由规则
{
path:'/login',
component:Login
},
{
path:'/home',
component:Home,
// 只要我们访问了home这个地址,我们就让他重定向到welcome这个地址 这个地方写斜线行,不写也行
redirect:'/welcome',
// 二级路由
children:[
{
//这个地方不能写单斜线
path:'welcome',
component:Welcome,
}
]
}
]
})
解释:为什么二级路由welcome需要单斜杠?
自我理解:在最开始页面加载的时候进行重定向 最开始的时候是/home 我重新定向到路径/welcome 这个第一次是需要加的 然后以后就不需要了;在这里/welcome虽然是二级路由但是替代了一级路由重定向,所以得加/
在Main主体中添加路由占位符
<!-- 主体 -->
<el-main>
<router-view></router-view>
</el-main>
Welcome.vue
<template>
<div>
<h3>Welcome!</h3>
</div>
</template>
<script>
export default {
name:'Welcome'
}
</script>
效果图:细心的朋友已经发现了下面这张图的路径已经不是home了,而是welcome,我们完成了重定向
二、左侧菜单改造为路由链接
将我们的二级菜单改造成路由菜单,这个也不是大家想的那样给每个二级菜单都加一个router-link,在Element-UI文档中有一个router属性,默认是false关闭,我们把他打开就行了
当我们没有添加这个属性的时候,我们点击二级菜单,并不能跳转到以index(下图中的index)作为path的路径中
怎么开启?如下图所示,在菜单el-menu上面添加 :router="true" 带边给整个侧边栏区域开启了路由模式
配置好了之后,我们点击侧边栏的任何一项,就会发现是空白页,而且路径也变了,而且这个路径的末尾数字就是v-for所对应的index的值,但是如果我不希望下面的路径后面是一串数字而且是一个看起来高档且易懂的路径该怎么办?
通过下图发现,其中还有一个path属性,但是path属性中的users并没有斜线,我们记得要添加
上图中的children内容也就是下图中的item.children
subItem中的内容就是children中的一条一条的内容
怎么修改代码呢?其中:index="'/'+subItem.path" 这个index地方已经做出了改变
<!-- 二级菜单 -->
<el-menu-item :index="'/'+subItem.path" v-for="subItem in item.children" :key="subItem.id">
<template slot="title">
<!-- 图标 -->
<i class="el-icon-menu"></i>
<!-- 一级导航名称 -->
<span>{{subItem.authName}}</span>
</template>
</el-menu-item>
效果图:
三、用户列表开发
当我们点击用户列表之后,在Main主体区域会显示出我们想要演示的内容
我们希望在Main主体区域显示,那我们就应该将路由添加在主页面下面,让它成为子路由
Users.vue
<template>
<div>
<h3>用户列表组件</h3>
</div>
</template>
<script>
export default {
name:"Users"
}
</script>
<style lang="less" scoped>
</style>
{
path:'/home',
component:Home,
// 只要我们访问了home这个地址,我们就让他重定向到welcome这个地址 这个地方写斜线行,不写也行
redirect:'/welcome',
// 二级路由
children:[
{
path:'/welcome',
component:Welcome,
},
{
path:'/users',
component:Users
}
]
}
注意这里不是单纯的嵌套路由,这里是重定向了的,所以这个子路由实际访问的路径还是一级路由
其他代码不变,我们已经在Main主体上写上了router-link
效果图:
进行到这里可能回想:刚刚我们不是已经使用Element-UI中菜单的:router="true"已经配置好路由了吗,为什么现在我们还要为其配置路由?
因为我们刚刚修改的时候,确实已经实现了路由了,但是跳转的页面不符合我们的要求,原始的是跳转到一个新的页面,而我们想的是跳转到Main主体上面去
3.1实现左侧二级菜单的高亮效果
当我们刷新页面之后,如下图所示:我们在用户列表区域,但是用户列表区域的二级菜单并没有显示出来,我们现在要将他显示出来
首先给菜单栏绑定一个我们自定义的activePath数据,:default-active="activePath"
<el-menu :default-active="activePath" :router="true" unique-opened :collapse="isCollapse" :collapse-transition="false"
background-color="#333744" text-color="#fff" active-text-color="#409BFF">
// 被激活的链接地址
activePath:''
在二级菜单绑定一个单击事件
<!-- 二级菜单 -->
<el-menu-item @click="saveNavState('/'+subItem.path)"
:index="'/'+subItem.path" v-for="subItem in item.children" :key="subItem.id">
// 保存链接的激活状态
saveNavState(activePath){
window.sessionStorage.setItem('activePath',activePath)
}
那我们怎么在一开始的时候就初始让用户列表是高亮状态呢?使用钩子函数。
但是这个我们在一打开主页面的时候并不会进入到用户管理之下的二级页面,因为最初的时候我们的activePath是空白符,当我们点击二级菜单后,我们的数据才进入到浏览器的本地存入,进而我们的钩子函数可以运行,实现二级菜单的高亮
created(){
// 获取左侧所有菜单(我们自己定义的一个方法)
this.getMenuList(),
this.activePath = window.sessionStorage.getItem('activePath')
},
但是!!!此时并没有完成!当我们随便点击一个二级菜单然后返回,会发现我们的用户列表并没有出现高亮状态,而且我们点击用户列表,也无法出现高亮状态,原因就是因为我们的浏览器本地存储值还依然是上一次的值,并没有修改,我们应该修改一下(当我们返回的时候created钩子函数已经加载完成了,但是加载的还是上一次的浏览器的存储值,这么做是不对的)
// 保存链接的激活状态
saveNavState(activePath){
window.sessionStorage.setItem('activePath',activePath)
this.activePath = activePath
}
四、绘制用户列表的基本UI结构
4.1面包屑导航区
在Element-UI找到面包屑的组件,我们要使用这个组件
Users.vue文件
<div>
<!-- 面包屑导航区域 -->
<el-breadcrumb separator-class="el-icon-arrow-right">
<!-- 当点击首页的时候跳转到/home -->
<el-breadcrumb-item :to="{ path: '/home' }">首页</el-breadcrumb-item>
<el-breadcrumb-item>用户管理</el-breadcrumb-item>
<el-breadcrumb-item>用户列表</el-breadcrumb-item>
</el-breadcrumb>
</div>
效果图:当我们点击“首页的时候还能够实现跳转”
4.2Card卡片
使用下图中简单的卡片组件
<!--卡片视图区 -->
<el-card >
</el-card>
添加全局样式
/* 面包屑 */
.el-breadcrumb{
margin-bottom: 15px;
font-size: 12px;
}
/* 卡片视图 */
.el-card{
/* 重置阴影区 */
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15) !important;
}
4.3 input输入框
<!--卡片视图区 -->
<el-card >
<!-- 搜索与添加区域 -->
<el-input placeholder="请输入内容">
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input>
</el-card>
但是我们发现这个搜索框沾满了整行,这不是我们想要的结果,我们无法添加按钮了,接下来我们要使用另一个组件Layout进行调整布局
4.4 Layout调整搜索框布局
<!--卡片视图区 -->
<el-card >
<!-- 搜索与添加区域 -->
<!-- Layout布局 :gutter="20"表示每一列(分栏)间隔的距离-->
<el-row :gutter="20">
<!-- 第一列 :span="7"指定宽度 一共24一行 -->
<el-col :span="10">
<el-input placeholder="请输入内容">
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input>
</el-col>
<!-- 第二列 -->
<el-col :span="4">
<el-button>添加用户</el-button>
</el-col>
</el-row>
</el-card>
五、获取用户列表数据
根据后端API接口获取数据
<script>
export default {
name:"Users",
data(){
return{
queryInfo:{
query:'',
pagenum:'1',
pagesize:2,
},
userList:[],
// 总数据条数
total:''
}
},
created(){
// 每当组件创建成功时就初始化用户界面
this.getUserList()
},
methods:{
async getUserList(){
// 使用axios发起get请求
const {data:res} = await this.$http.get('users',{params:this.queryInfo})
if(res.meta.status !==200)
return this.$message.error('获取用户列表失败!')
this.userList = res.data.users
this.total = res.data.total
}
}
}
</script>
六、渲染用户列表数据
6.1渲染用户列表数据
依然使用Element-UI中的组件渲染我们的用户数据
<!--卡片视图区 -->
<el-card >
<!-- 搜索与添加区域 -->
<!-- Layout布局 :gutter="20"表示每一列(分栏)间隔的距离-->
<el-row :gutter="20">
<!-- 第一列 :span="7"指定宽度 一共24一行 -->
<el-col :span="10">
<el-input placeholder="请输入内容">
<el-button slot="append" icon="el-icon-search"></el-button>
</el-input>
</el-col>
<!-- 第二列 -->
<el-col :span="4">
<el-button>添加用户</el-button>
</el-col>
</el-row>
<!-- 用户列表区 border是给表格添加边框线 stripe是隔行变色效果-->
<el-table :data="userList" border stripe>
<!-- label指定列明 -->
<el-table-column label="姓名" prop="username"></el-table-column> <el-table-column label="姓名" prop="username"></el-table-column>
<el-table-column label="邮箱" prop="email"></el-table-column>
<el-table-column label="电话" prop="mobile"></el-table-column>
<el-table-column label="角色" prop="role_name"></el-table-column>
<el-table-column label="状态" prop="mg_state"></el-table-column>
<el-table-column label="操作" ></el-table-column>
</el-table>
</el-card>
6.2为用户列表添加索引列
新添加一列table-column,然后指定type="index"
6.3 改造状态列的显示效果(按需渲染)
Vue插槽---默认插槽、具名插槽、作用域插槽_我爱布朗熊的博客-CSDN博客
使用switch开关组件,除此之外我们还要使用一个作用域插槽
效果图:
这个地方的 v-slot="scope" 是已经封装好的,其中scope使我们自己命名的,至于为什么用这个名字,是官网文档用的,当然我们这里也可以给她改名字,这个无所谓
我们要记得将状态栏后面的prop删除,因为我们如果同时指定prop和作用域插槽,作用域插槽会把prop给覆盖掉
<!-- 用户列表区 border是给表格添加边框线 stripe是隔行变色效果-->
<el-table :data="userList" border stripe>
<!-- label指定列明 -->
<el-table-column type="index" label="编号" ></el-table-column>
<el-table-column label="姓名" prop="username"></el-table-column>
<el-table-column label="邮箱" prop="email"></el-table-column>
<el-table-column label="电话" prop="mobile"></el-table-column>
<el-table-column label="角色" prop="role_name"></el-table-column>
<el-table-column label="状态" >
<template slot-scope="scope">
<!-- {{scope.row}} 这个是这一行的数据 包括姓名、邮箱、状态等等 -->
<el-switch v-model="scope.row.mg_state">
</el-switch>
</template>
</el-table-column>
<el-table-column label="操作" ></el-table-column>
</el-table>
七、插槽形式自定义列的渲染
我们首先来看按钮以及文字提示的参数,接下来我们会有用处
<el-table-column label="操作" >
<!-- 插槽 -->
<template slot-scope="scope">
<!-- 修改按钮 -->
<el-button size="mini" type="primary" icon="el-icon-edit"></el-button>
<!-- 删除按钮 -->
<el-button size="mini" type="danger" icon="el-icon-delete"></el-button>
<!--effect 提示文字的背景颜色 :enterable="false" 默认自动隐藏 -->
<el-tooltip :enterable="false" class="item" effect="dark" content="分配角色" placement="top">
<!-- 分配角色按钮 -->
<el-button size="mini" type="warning" icon="el-icon-setting"></el-button>
</el-tooltip>
</template>
</el-table-column>
八、实现数据的分页效果
我们用这个功能比较全的分页组件
<!-- 分页区域 -->
<!-- @size-change="handleSizeChange" -->
<!-- @current-change="handleCurrentChange" 在当前页改变的时候,触发handleCurrentChange -->
<!-- :page-sizes="[1, 2, 5,10 ]" 每页可以显示1 2 5 10 具体多少可以根据我们自己选 -->
<!-- :page-size是一个数组 -->
<!-- :page-size="queryInfo.page-size" 当前每页显示多少条数据 -->
<!-- layout="total, sizes, prev, pager, next, jumper" layout指定页面上展示什么功能组件
total展示一共多少条 sizes展示每页显示多少条的一个下拉菜单 -->
<!-- :total="total"> 绑定我们有多少条数据 -->
<el-pagination
@size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="queryInfo.pagenum"
:page-sizes="[1, 2, 5,10 ]"
:page-size="queryInfo.pagesize"
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
<script>
export default {
name:"Users",
data(){
return{
queryInfo:{
query:'',
// 当前的页数
pagenum:'1',
// 每页显示多少条数据 默认每页显示两条
pagesize:2,
},
userList:[],
// 总数据条数
total:''
}
},
created(){
// 每当组件创建成功时就初始化用户界面
this.getUserList()
},
methods:{
async getUserList(){
// 使用axios发起get请求
const {data:res} = await this.$http.get('users',{params:this.queryInfo})
if(res.meta.status !==200)
return this.$message.error('获取用户列表失败!')
this.userList = res.data.users
this.total = res.data.total
},
// 监听pagesize改变的事件
handleSizeChange(newSize){
// 这个pagesize就是空值每页显示多少条的
this.queryInfo.pagesize = newSize
// 当我们重新设置了每页显示多少条之后,我们可以重新发起一个请求获取数据来渲染页面
this.getUserList()
},
// 监听页码值改变的事件
handleCurrentChange(newPage){
// 这个地方也是同理
this.queryInfo.pagenum = newPage
this.getUserList()
}
}
}
</script>
更多推荐
所有评论(0)