【第一个Vue上手小项目Day4】史上最简单的Element-table表格+Pagination 分页(前后端结合)
目录
- 序
- 正文
- 一、前端设计
- 1. element-Table 表格
- 2. element-Pagination 分页
- 二、结合后端
- 三、遇见问题及解决
- 四、总结&源码
序
前言:
本来搭建好Vue和Springboot前后端框架之后,就不想重复CRUD基础
表格的增删改查,觉得ajax
是互通的,没有必要再重复重复这些工作。因为,一个小项目要善始善终,不能只有登录就没有后续了。尝试一下Element-ui表格,下拉框,进度条
等;Vue引入echarts
或其他样式;就不会知道其中的bug和坑,所以,现在开始挖坑…
思路:
参考任意一个后台管理模板的内容:
- 主界面:大概是以下内容,表格、图表、进度条
- 分目录:
- 表格:基础的CRUD、分页,更多有导出表格Excel等。
更多内容参考:林鑫的demo
- 表格:基础的CRUD、分页,更多有导出表格Excel等。
本文目标: 在之前vue+Springboot的基础上,实现基础表格,echarts
,话不多说,开始挖坑~
提前预告:
用过:Element-table表格+Pagination 分页
之后,
? ElementUI是目前博主用过最赞的前端表格处理工具,没有之一 ?
正文
一、前端设计
1. element-Table 表格
参考:element-Table 表格
根据官网api文档,综合了一下表格功能:
左侧全选和反选,日期筛选和排序,标签筛选,关键词搜索,自定义编辑和删除按钮
(当然了,这仅是前端界面,根据文档,第一次写,差不多一个小时能全部搞懂,UI框架nice~)
静态页面UserList.vue
<template><div><el-button @click="toggleSelection([tableData[1], tableData[2]])">切换第二、第三行的选中状态</el-button><el-button @click="toggleSelection()">取消选择</el-button><el-button @click="resetDateFilter">清除日期过滤器</el-button><el-button @click="clearFilter">清除所有过滤器</el-button><el-table ref="filterTable" :data="tableData.filter(data => !search || data.name.toLowerCase().includes(search.toLowerCase()))" :default-sort="{prop: 'date', order: 'descending'}" bordertooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange"><el-table-column type="selection" width="55"></el-table-column><el-table-column prop="date" label="日期" sortable width="180" column-key="date" :filters="[{text: '2016-05-01', value: '2016-05-01'}, {text: '2016-05-02', value: '2016-05-02'}, {text: '2016-05-03', value: '2016-05-03'}, {text: '2016-05-04', value: '2016-05-04'}]":filter-method="filterHandler"></el-table-column><el-table-column prop="name" label="姓名" width="180"></el-table-column><el-table-column prop="address" label="地址" :formatter="formatter"></el-table-column><el-table-column prop="tag" label="标签" width="100" :filters="[{ text: '家', value: '家' }, { text: '公司', value: '公司' }]":filter-method="filterTag" filter-placement="bottom-end"><template slot-scope="scope"><el-tag :type="scope.row.tag === '家' ? 'primary' : 'success'" disable-transitions>{{scope.row.tag}}</el-tag></template></el-table-column><el-table-columnalign="right"><template slot="header" slot-scope="scope"><el-inputv-model="search"size="mini"placeholder="输入姓名关键字搜索"/></template><template slot-scope="scope"><el-buttonsize="mini"@click="handleEdit(scope.$index, scope.row)">Edit</el-button><el-buttonsize="mini"type="danger"@click="handleDelete(scope.$index, scope.row)">Delete</el-button></template></el-table-column></el-table></div>
</template><script>export default {data() {return {tableData: [{date: '2016-05-01',name: '王小虎',address: '上海市普陀区金沙江路 1518 弄',tag: '家'}, {date: '2016-05-02',name: '李小虎',address: '上海市普陀区金沙江路 1517 弄',tag: '公司'}, {date: '2016-05-03',name: '张小虎',address: '上海市普陀区金沙江路 1519 弄',tag: '家'}, {date: '2016-05-04',name: '王小虎',address: '上海市普陀区金沙江路 1516 弄',tag: '公司'}],multipleSelection: [],search: ''}},methods: {//多行全选和反选toggleSelection(rows) {if (rows) {rows.forEach(row => {this.$refs.filterTable.toggleRowSelection(row);});} else {this.$refs.filterTable.clearSelection();}},handleSelectionChange(val) {//反选this.multipleSelection = val;},//排序formatter(row, column) {return row.address;},//标签查找和清除标签resetDateFilter() {this.$refs.filterTable.clearFilter('date');},clearFilter() {this.$refs.filterTable.clearFilter();},filterTag(value, row) {return row.tag === value;},filterHandler(value, row, column) {const property = column['property'];return row[property] === value;},//编辑handleEdit(index, row) {console.log(index, row);},//删除handleDelete(index, row) {console.log(index, row);}}}
</script>
2. element-Pagination 分页
参考:element-Pagination 分页
<template><div class="block"><el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage":page-sizes="[10, 20, 30, 40]" :page-size="10" layout="total, sizes, prev, pager, next, jumper" :total="40" background></el-pagination></div>
</template>
<script>export default {methods: {handleSizeChange(val) {console.log(`每页 ${val} 条`);},handleCurrentChange(val) {console.log(`当前页: ${val}`);}},data() {return {currentPage: 4};}}
</script>
二、结合后端
后端用springboot结合aop封装:【Springboot学习 | 6】Lombok优雅的编码+Aop异常统一管理
返回:code、data、message、success
主要Ajax:
created() {this.getUserList();},methods: {getUserList() {this.$ajax.get('/user/aop2').then((res) => { //axios发送get请求if (res.data) {console.log(res.data)this.userList = res.data.data;} else {alert("查询失败")}})}}
完整userList.vue
:
- 注意data的名称
<template><div><el-button @click="toggleSelection([userList[1], userList[2]])">切换第二、第三行的选中状态</el-button><el-button @click="toggleSelection()">取消选择</el-button><el-button @click="clearFilter">清除所有过滤器</el-button><el-table ref="filterTable" :data="userList.slice((currentPage-1)*pagesize,currentPage*pagesize).filter(data => !search || data.name.toLowerCase().includes(search.toLowerCase()))":default-sort="{prop: 'id', order: 'ascending'}" border tooltip-effect="dark" style="width: 100%" @selection-change="handleSelectionChange"><el-table-column type="selection" width="55"></el-table-column><el-table-column prop="id" label="id" sortable width="180"></el-table-column><el-table-column prop="name" label="姓名" width="180"></el-table-column><el-table-column prop="age" label="年龄" width="180"></el-table-column><el-table-column prop="address" label="地址" width="180" :filters="[{ text: '重庆', value: '重庆' }, { text: '北京', value: '北京' },{ text: '上海', value: '上海' }]":filter-method="filterTag" filter-placement="bottom-end"><template slot-scope="scope"><el-tag :type="scope.row.address === '重庆' ? 'primary' : 'success'" disable-transitions>{{scope.row.address}}</el-tag></template></el-table-column><el-table-column align="right"><template slot="header" slot-scope="scope"><el-input v-model="search" size="mini" placeholder="输入姓名关键字搜索" /></template><template slot-scope="scope"><el-button size="mini" @click="handleEdit(scope.$index, scope.row)">Edit</el-button><el-button size="mini" type="danger" @click="handleDelete(scope.$index, scope.row)">Delete</el-button></template></el-table-column></el-table><div class="block"><el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page="currentPage":page-sizes="[10, 20, 30, 40]" :page-size="pagesize" layout="total, sizes, prev, pager, next, jumper" :total="userList.length"background></el-pagination></div></div>
</template><script>export default {data() {return {userList: [],multipleSelection: [], //全选和反选标记search: '', //关键词查找currentPage: 1 ,//最初显示默认要跳转的一页pagesize:10}},created() {this.getUserList();},methods: {//多行全选和反选toggleSelection(rows) {if (rows) {rows.forEach(row => {this.$refs.filterTable.toggleRowSelection(row);});} else {this.$refs.filterTable.clearSelection();}},handleSelectionChange(val) { //反选this.multipleSelection = val;},//排序formatter(row, column) {return row.address;},//标签查找和清除标签resetDateFilter() {this.$refs.filterTable.clearFilter('address');},clearFilter() {this.$refs.filterTable.clearFilter();},filterTag(value, row) {return row.address === value;},filterHandler(value, row, column) {const property = column['property'];return row[property] === value;},//编辑handleEdit(index, row) {console.log(index, row);},//删除handleDelete(index, row) {console.log(index, row);},//分页handleSizeChange(size) {console.log(`每页 ${size} 条`);this.pagesize = size;},handleCurrentChange(currentPage) {console.log(`当前页: ${currentPage}`);this.currentPage = currentPage;},getUserList() {this.$ajax.get('/user/aop2').then((res) => { //axios发送get请求if (res.data) {console.log(res.data)this.userList = res.data.data;} else {this.$message({type: 'error',message: '查询失败',showClose: true})}})}}}
</script>
最终效果: 以下全部根据官网教程写出来的,稍稍改动整合:
参考:element-Table 表格
关键词查找(姓名模糊查询)
通过设置Scoped slot
来自定义表头。
search方法也比较简单,用的分词过滤器类似原理,如果名称是王小虎
,则输入王
即可查询出来:
el-table :data="tableData.filter(data => !search || data.name.toLowerCase().includes(search.toLowerCase()))"
data() {return {userList: [],multipleSelection: [], //全选和反选标记search: '', //关键词查找currentPage: 1 ,//最初显示默认要跳转的一页pagesize:10}}
多选,排序
多选: 实现多选非常简单: 手动添加一个
el-table-column
,设type
属性为selection
即可;@selection-change="handleSelectionChange"
是控制反选,改变选择状态;//多行全选和反选toggleSelection(rows) {if (rows) {rows.forEach(row => {this.$refs.filterTable.toggleRowSelection(row);});} else {this.$refs.filterTable.clearSelection();}},handleSelectionChange(val) { //反选this.multipleSelection = val;},
排序:
el-table :default-sort = "{prop: 'date', order: 'descending'}"
是降序,ascending是升序。//排序formatter(row, column) {return row.address;},
- 分页效果
除了参考官网:element-Pagination 分页
分页函数加上变量:
//分页handleSizeChange(size) {this.pagesize = size;},handleCurrentChange(currentPage) {this.currentPage = currentPage;}
很重要的一步是在el-table标签中:data属性要加上监听:
userList.slice((currentPage-1)*pagesize,currentPage*pagesize)
- 标签筛选
data() {return {userList: [],multipleSelection: [], //全选和反选标记search: '', //关键词查找currentPage: 1 ,//最初显示默认要跳转的一页pagesize:10}}。。。。。。。。。。//标签查找和清除标签resetDateFilter() {this.$refs.filterTable.clearFilter('address');//注意对应的标签},clearFilter() {this.$refs.filterTable.clearFilter();},filterTag(value, row) {return row.address === value;},filterHandler(value, row, column) {const property = column['property'];return row[property] === value;},
三、遇见问题及解决
问题:
error:The template root requires exactly one element.
原因:因为vue的模版中只有能一个根节点,所以在< template>
中插入第二个元素就会报错
解决:将中的元素先用一个< div>
包起来。<template><div><el-button>XXX</el-button><el-table></el-table></div> </template>
中文乱码,解决方法:后端配置application.properties加上
&characterEncoding=UTF8
四、总结&源码
总结:
element-UI框架分页,查询,排序
都是全查询get
到全部信息之后,再对数据进行分页,排序
等:
首先,element-table比之前自己用各原生page-taglib ?、PageHelper分页 ?、LayUI ? 分页方法都要nb‘,大赞Pagination 分页
?
其次,分词 查询、排序、筛选 思想,比之前我自己肝了三天的条件查询,然后再后端控制注入 要科学。
本次学习颇有收获。
源码:
- 前端: Vue-Day4
- 后端:Springboot-Day7
- sql:t_user
【第一个Vue上手小项目Day4】史上最简单的Element-table表格+Pagination 分页(前后端结合)相关推荐
- 【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面
文章目录 0. 项目介绍 电商管理系统(Element-UI) 开发模式 前端技术栈 后端技术栈 1. 配置--初始化 前端项目 ① 安装 Vue 脚手架 ② 通过 Vue 脚手架创建项目 ③ 配置 ...
- 跟我一起做一个vue的小项目(十一)
接下来我们进行的是详情页动态路由及banner布局 先看页面的效果 下面是代码部分 <template><div><div class="banner" ...
- 跟我一起做一个vue的小项目(九)
接下来我们进行的就是城市列表页面数据额动态渲染. 也是在mock数据,进行动态渲染 //city.json {"ret": true,"data":{" ...
- 0301 - 一个比价的小项目
这两天帮朋友做了个 比价 的小项目,主要是为了练手 Vue 及相关网站开发. 主要功能: 批量查询产品对应的京东价格 手动根据京东价格调整批发价格 将产品及价格信息,以网页形式分享出去 由于是私人项目 ...
- c语言为什么要建项目,一个C语言小项目为什么都说牛逼
原标题:一个C语言小项目为什么都说牛逼 意在鼓励C语言学者.更有兴趣,学习更富有创业和乐趣! 推荐加学习交流群:658807522 可以在一起学习交流,既是参赛选手,又是学者,也可以先学习再参赛,反正 ...
- 手把手教你完成一个数据科学小项目(7):经纬度获取与BDP可视化
前言 请先阅读"中国年轻人正带领国家走向危机",这锅背是不背? 一文,以对"手把手教你完成一个数据科学小项目"系列有个全局性的了解. 本系列代码统一开源在Git ...
- 昨天找的一个地推小项目,58推客
昨天找的一个地推小项目,58推客,分享给大家. 赚点零花钱还可以,赚大钱是不可能的了. 有人卖这个信息差要60块钱,不过一律要交钱的,我都直接当骗子处理. 毕竟我是受过教训的. 今天尝试跑了几家,基本 ...
- 从0到1完成一个Vue后台管理项目(九、引入Breadcrumb面包屑,更改bug)
往期 从0到1完成一个Vue后台管理项目(一.创建项目) 从0到1完成一个Vue后台管理项目(二.使用element-ui) 从0到1完成一个Vue后台管理项目(三.使用SCSS/LESS,安装图标库 ...
- 手把手教你完成一个数据科学小项目(9):情感分析与词云
前言 请先阅读"中国年轻人正带领国家走向危机",这锅背是不背? 一文,以对"手把手教你完成一个数据科学小项目"系列有个全局性的了解. 本系列代码统一开源在Git ...
- python导入同级包_python小课堂15 - 史上最详细的包和模块import讲解篇
python小课堂15 - 史上最详细的包和模块import讲解篇 前言 在大量的代码设计中,我们不可能将所有代码都写在一个.py文件,所以有了包.模块,而为了代码可以重复利用(复用性),就有了类.函 ...
最新文章
- 对items函数的理解
- On Tutorial with Caffe--a Hands DIY DL for Vision
- 转账为demo,spring事务
- 【转】浅论ViewState及其与Session的关系
- esp8266教程:文件系统之spiffs
- thinkphp集成webuploader实战
- Python爬取URP教务系统课程表并保存到excel
- 思科ccie和华为hcie中交换机环路的产生原因和解决方法
- elasticsearch从入门到入门系列(一)---简单介绍及安装
- 只读存储器,并行存储器
- php 和 photoshop,pscc和ps有什么区别
- get crash report binary image adress on ios
- js Javascript中调用对象内函数.(字符串函数名)
- igmp组播实验 @yx
- mysql查询至少学过学号为“s001”同学所有课的其他同学学号和姓名
- AFO(Maybe)总结
- cisco无线AP胖瘦区分
- 元数据治理:产品方案介绍及案例实践
- python-tems,keys,values
- poj 2228 环形DP
热门文章
- 系统架构设计笔记(74)—— 企业信息化与电子商务
- 非相参积累 matlab,非相参积累增益,比相参积累增益更难计算?
- 算24(递归)--算法学习
- 最大似然函数,琴生不等式
- Spark编程核心抽象—RDD
- 当cmd里安装不了Appium-Python-Client时,Requirement already satisfied: Appium-Python-Client in
- linux中IGV的运行,科学网—使用UCSC和IGV查看reads在基因组上分布情况 - 熊朝亮的博文...
- 工业机器人视觉实训平台
- Approaching ANXIETY DISORDER
- 如何确定一台电脑配置的高低