前端Vue+Element UI案例:通用后台管理系统-用户管理:Table表格增删查改Pagination分页搜索框
Posted karshey
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端Vue+Element UI案例:通用后台管理系统-用户管理:Table表格增删查改Pagination分页搜索框相关的知识,希望对你有一定的参考价值。
文章目录
上一篇: 【前端】Vue+Element UI案例:通用后台管理系统-用户管理:Form表单填写、Dialog对话框弹出
目标
总体是这样:
需求:本篇主要是Table表格增删查改、Pagination分页。上篇已经完成了表单、对话框弹出。
- 表格Table显示用户数据
- 用户数据由Mock随机生成,提供后端接口
- 删除:可以删除用户数据,弹出消息提示
- 搜索框:可以搜索用户数据
- 分页效果
代码
0.结构
上篇已经完成了提交功能,但由于现在还没有表格,不知道自己写的对不对。我们先迅速地用组件把表格写出来。
当el-table元素中注入data对象数组后,在el-table-column中用prop属性来对应对象中的键名即可填入数据,用label属性来定义表格的列名。可以使用width属性来定义列宽。
<div class="common-table">
<!-- 用户数据Table -->
<el-table :data="tableData" stripe style="width: 100%">
<el-table-column prop="name" label="姓名">
</el-table-column>
<el-table-column prop="age" label="年龄">
</el-table-column>
<el-table-column prop="sex" label="性别">
</el-table-column>
<el-table-column prop="birth" label="出生日期">
</el-table-column>
<el-table-column prop="addr" label="地址">
</el-table-column>
<!-- 自定义列 -->
</el-table>
<!-- 分页 -->
</div>
效果:
我们先测试一下提交功能:
提交本身没问题,但细节有点问题:我们要规范一下出生日期的格式。
代码:添加value-format="yyyy-MM-DD"
<el-form-item label="出生日期">
<el-form-item prop="birth">
<el-date-picker type="date" placeholder="请选择日期" v-model="form.birth" value-format="yyyy-MM-DD">
</el-date-picker>
</el-form-item>
</el-form-item>
1.按钮-删除
需求:
- 自定义列:列名操作
- 按钮:编辑、删除
- 点击后有弹窗
自定义列:
<el-table-column label="操作">
<template slot-scope="scope">
<el-button
size="mini"
@click="handleEdit(scope.$index, scope.row)">编辑</el-button>
<el-button
size="mini"
type="danger"
@click="handleDelete(scope.$index, scope.row)">删除</el-button>
</template>
</el-table-column>
点击后的弹窗功能:
methods如下:
this.$confirm('此操作将永久删除该文件, 是否继续?', '提示',
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
).then(() =>
this.$message(
type: 'success',
message: '删除成功!'
);
).catch(() =>
this.$message(
type: 'info',
message: '已取消删除'
);
);
效果:删除数据+弹窗。
2.按钮-编辑
需求:
- 点击编辑后:打开表单
- 把当前用户信息填上去(深拷贝)
显然会调用update的接口。
表单有新建和编辑两种打开方式:
- 新建:打开空表单,左上角为“新建”,调用接口为create
- 编辑:打开表单,自动填进当前用户信息,左上角为“编辑”,调用接口为update
因此我们用一个变量modalType来表示是新建(0)还是编辑(1)。
代码:点击编辑按钮后标记modalType为1,打开表单,进行深拷贝。
// 编辑按钮
handleEdit(index)
this.modalType = 1
this.openForm()
// 深拷贝
this.form = JSON.parse(JSON.stringify(index))
,
// 打开表单
openForm()
this.dialogVisible = true
接下来的逻辑判断就由submit来实现:若modalType为0,则新增;否则修改:
// 表单提交
submit()
// 要用箭头函数,若用function会报错,不知道为什么
this.$refs.form.validate((valid) =>
// 符合校验
if (valid)
// 提交数据
if (this.modalType === 0)
// 新增
createUser(this.form).then(() =>
this.getList()
)
else
// 编辑
updateUser(this.form).then(() =>
this.getList()
)
// 清空,关闭
this.closeDialog()
)
效果:确实显示在了表单中。显然还有一些问题,比如日期显示的是错误的,性别显示的是数字。我们在下一节修改它。
3.debug
debug:
- 点击新建则表单左上角显示新建,点击编辑则表单左上角显示编辑
- 性别显示“男女”而非10
新建与编辑:
<el-dialog
:title="modalType == 0 ? '新建' : '编辑'"
:visible.sync="dialogVisible"
width="50%"
:before-close="closeDialog">
性别显示:
<el-table-column prop="sex" label="性别">
<template slot-scope="scope">
<span> scope.row.sex == 1 ? '男' : '女' </span>
</template>
</el-table-column>
效果:在表格中的性别显示已经改过来了。至于为什么年龄匹配不上,且名为娟的会是男性…因为数据全是随机生成的(详见user.js中的mock.random)
但是出现了新的问题,点击编辑后自动填入的性别还是1和0,为什么呢?
原因:后端返回的数据中sex是integer(0,1)
for (let i = 0; i < count; i++)
List.push(
Mock.mock(
id: Mock.Random.guid(),
name: Mock.Random.cname(),
addr: Mock.mock('@county(true)'),
'age|18-60': 1,
birth: Mock.Random.date(),
sex: Mock.Random.integer(0, 1)
)
)
而前端的表单中的value是String:
<el-form-item label="性别" prop="sex">
<el-select v-model="form.sex" placeholder="请输入性别">
<el-option label="男" value="1"></el-option>
<el-option label="女" value="0"></el-option>
</el-select>
</el-form-item>
解决方法:动态绑定value,让它可以更改:
<el-option label="男" :value="1"></el-option>
<el-option label="女" :value="0"></el-option>
效果:
4.样式
当前样式:鼠标滚轮往下滑,可以看到表格的所有数据都显示在一页。许多数据会把table的高度撑的很大。我们要限制table的宽高。
在html中增加Attribute:height
<el-table
:data="tableData"
stripe
style="width: 100%"
height="90%">
这样会受控于外部样式,所以我们要给外部div也写上样式。
最大的div的高度占浏览器100%,common-table高度为父级的90%,于是el-table表格的高度为common-table的90%。
.manage
height: 100%;
.common-table
height: 90%;
效果:
5.分页Pagination:功能
<el-pagination
layout="prev, pager, next"
:total="1000">
</el-pagination>
这只是结构,我们还要完成点击对应页码就跳转到对应Table页的效果:
参数为点击的页码:
// 改变页码
currentChange(val)
console.log(val);
到这里我们可以确定:我们能通过currentChange获取到点击的页码,至于如何完成跳转呢?由于表格中显示哪些数据由getList这个函数决定,而getList又是由后端接口中的getUserList决定的: 我们可以看一下后端的接口文档。
/**
* 获取列表
* 要带参数 name, page, limt; name可以不填, page,limit有默认值。
* @param name, page, limit
* @return code: number, count: number, data: *[]
*/
getUserList: config =>
const name, page = 1, limit = 20 = param2Obj(config.url)
// console.log('name:' + name, 'page:' + page, '分页大小limit:' + limit)
const mockList = List.filter(user =>
if (name && user.name.indexOf(name) === -1 && user.addr.indexOf(name) === -1) return false
return true
)
const pageList = mockList.filter((item, index) => index < limit * page && index >= limit * (page - 1))
return
code: 20000,
count: mockList.length,
list: pageList
所以page页码数可以当作参数传给getUser。由注释可知:要带参数 name, page, limt; name可以不填, page,limit有默认值。显然传入的是一个对象。于是我们在data中定义这个对象:
- page:要展示第page页
- limit:每页limit条数据,这里是默认值
pageData:
page:1,
limit:20
每次点击分页时就修改pageData.page,然后把它传给getUser。
// 获取列表数据
getList()
// 由接口文档知传入一个对象
getUser(params:...this.pageData).then((data) =>
this.tableData = data.data.list
)
效果:数据竟然消失了?
看一下控制台,原来错误出在::8081/api/user/get?page=1&limit=20:1 Failed to load resource: the server responded with a status of 404 (Not Found)
由于我们之前定义的getUser是get方法,它的参数是会在url里的,而我们在mock里定义的:
Mock.mock('/api/user/get',user.getUserList)
是写死的,/api/user/get?page=1&limit=20
与/api/user/get
是匹配不上的!
解决方法:正则表达式。
Mock.mock(/\\/api\\/user\\/get/,user.getUserList)
getList:
getList()
// 由接口文档知传入一个对象
getUser( params: ...this.pageData ).then((data) =>
this.tableData = data.data.list
this.total = data.data.count || 0
)
改变页码:
// 改变页码
currentChange(val)
this.pageData.page = val
this.getList()
效果:
第一页:
第三页:
6.分页Pagination:样式
右下角。子绝父相。
.common-table
height: 90%;
position: relative;
.pager
position: absolute;
right:20px;
bottom: 0;
效果:(忽略搜索框!分页的样式是我最后写的…)
7.搜索框:功能
搜索框,但是用的是表单组件:
html:
<el-form>
<el-form-item>
<el-input v-model="searchForm.name" placeholder="请输入名称"></el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="search">查询</el-button>
</el-form-item>
</el-form>
由于table显示的数据是本页数据+搜索到的数据的交集,我们要修改getList:
getList()
// 由接口文档知传入一个对象:要返回的是当前页面数据和搜索到的数据的交集
getUser( params: ...this.pageData,...this.searchForm ).then((data) =>
this.tableData = data.data.list
this.total = data.data.count || 0
)
但凡触发了搜索事件:重新获取table数据即可。
search()
this.getList()
效果:
8.搜索框:样式
让新建按钮和搜索框并排:flex。
让搜索框的输入框和按钮并排:inline。
html:
<el-form :inline="true">
css:
.manage
height: 100%;
.manage-header
display: flex;
justify-content: space-between;
align-items: center;
.common-table
height: 90%;
效果:
总效果
总代码
修改和创建的文件
User.vue
<template>
<div class="manage">
<div class="manage-header">
<!-- 新增按钮 -->
<el-button type="primary" @click="handlecreate">+ 新增</el-button>
<!-- 对话框:点击新增或编辑才会弹出表单 -->
<!-- :before-close="closeDialog" 点击关闭的x之前要做的事情 -->
以上是关于前端Vue+Element UI案例:通用后台管理系统-用户管理:Table表格增删查改Pagination分页搜索框的主要内容,如果未能解决你的问题,请参考以下文章
前端Vue+Element UI案例:通用后台管理系统-项目总结
前端Vue+Element UI案例:通用后台管理系统-登陆不同用户显示不同菜单动态添加路由
前端Vue+Element UI案例:通用后台管理系统-导航栏
前端Vue+Element UI案例:通用后台管理系统-Echarts图表:折线图柱状图饼状图