使用Vue+ElementUI实现前端分页
背景
项目中要做一个公共的附件展示列表,针对某个模块某条记录展示,因此附件不会是大数据量,采用前端分页,使用Vue.JS+ElementUI布局展示,axios请求数据。
步骤
一、Html页面中引入JS、CSS
<!-- 引入JS -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<!-- import element-ui JavaScript -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<!-- import axios JavaScript -->
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
建议直接下载js文件到本地,在引入到页面。
二、页面中添加ElementUI的表格
根据项目的需要可以自行选择:https://element.eleme.cn/#/zh-CN/component/table
1 <el-table :data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize).filter(data => !search || data.foton_fileoldname.toLowerCase().includes(search.toLowerCase()))" border stripe fit empty-text="暂无数据" 2 style="width: 100%"> 3 <el-table-column prop="foton_obsfilesid" 4 label="ID" 5 v-if="isIDShow"> 6 </el-table-column> 7 <el-table-column label="文件名称" 8 prop="foton_fileoldname"> 9 </el-table-column> 10 <el-table-column label="附件所属类型" 11 prop="foton_type"> 12 </el-table-column> 13 <el-table-column label="上传时间" 14 prop="createdon"> 15 </el-table-column> 16 <el-table-column align="right"> 17 <template slot="header" slot-scope="scope"> 18 <el-input v-model="search" 19 size="mini" 20 placeholder="输入关键字搜索" /> 21 </template> 22 <template slot-scope="scope"> 23 <el-button size="mini" icon="el-icon-search" circle 24 @click="handleEdit(scope.$index, scope.row)"></el-button> 25 <el-button size="mini" 26 @click="handleEdit(scope.$index, scope.row)">下载</el-button> 27 <el-button size="mini" 28 type="danger" 29 @click="handleDelete(scope.$index, scope.row)">删除</el-button> 30 </template> 31 </el-table-column> 32 </el-table>
三、引入分页组件
<div class="block" style="float:right">
<span class="demonstration"></span>
<el-pagination @size-change="handleSizeChange"
@current-change="handleCurrentChange"
:current-page="currentPage"
:page-sizes="pageSizes"
:page-size="pageSize"
background
layout="total, sizes, prev, pager, next, jumper"
:total="total">
</el-pagination>
</div>
分页组件的使用,详细见ElementUI官网
四、JS数据与方法
表格的数据绑定不必多说,通过axios请求数据绑定到tableData集合,表格列prop与集合字段保持一致即可。
前端分页相关是重点,pageSize、pageSizes、currentPage、total字段:
data: { pageSize: 10, pageSizes: [5, 10, 15, 20, 30, 40, 50], // select选项设置:条/页 currentPage: 1, total: 0, } 分页组件方法: handleSizeChange(val) { this.pageSize = val; }, handleCurrentChange(val) { this.currentPage = val; },
前端分页实现核心就是,el-table组件的data对象数组,通过数组的slice方法,从已有的数组中返回选定的元素。
:data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize)“
还可以在进行过滤筛选:
:data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize).filter(data => !search || data.foton_fileoldname.toLowerCase().includes(search.toLowerCase()))"
至此,使用Vue+ElementUI实现前端分页就实现了。
效果如下:
拓展
附上完整的代码:
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5 <title>Obs文件列表</title> 6 <!-- 引入样式 --> 7 <link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css"> 8 </head> 9 <body> 10 <div id="app"> 11 <el-button @click="visible = true">模态框按钮</el-button> 12 <el-dialog :visible.sync="visible" title="提示"> 13 <p>模态框</p> 14 </el-dialog> 15 <el-table :data="tableData.slice((currentPage-1)*pageSize,currentPage*pageSize).filter(data => !search || data.foton_fileoldname.toLowerCase().includes(search.toLowerCase()))" border stripe fit empty-text="暂无数据" 16 style="width: 100%"> 17 <el-table-column label="文件名称" 18 prop="foton_fileoldname"> 19 </el-table-column> 20 <el-table-column label="类型" 21 prop="filetype"> 22 </el-table-column> 23 <el-table-column label="上传时间" 24 prop="createdon"> 25 </el-table-column> 26 <el-table-column align="right"> 27 <template slot="header" slot-scope="scope"> 28 <el-input v-model="search" 29 size="mini" 30 placeholder="输入关键字搜索" /> 31 </template> 32 <template slot-scope="scope"> 33 <el-button size="mini" 34 @click="handleEdit(scope.$index, scope.row)">下载</el-button> 35 <el-button size="mini" 36 type="danger" 37 @click="handleDelete(scope.$index, scope.row)">删除</el-button> 38 </template> 39 </el-table-column> 40 </el-table> 41 <div class="block" style="float:right"> 42 <span class="demonstration"></span> 43 <el-pagination @size-change="handleSizeChange" 44 @current-change="handleCurrentChange" 45 :current-page="currentPage" 46 :page-sizes="pageSizes" 47 :page-size="pageSize" 48 background 49 layout="total, sizes, prev, pager, next, jumper" 50 :total="total"> 51 </el-pagination> 52 </div> 53 </div> 54 <!-- import Vue before Element --> 55 <script src="https://unpkg.com/vue/dist/vue.js"></script> 56 <!-- import JavaScript --> 57 <script src="https://unpkg.com/element-ui/lib/index.js"></script> 58 <script> 59 new Vue({ 60 el: '#app', 61 data: { 62 visible: false, 63 tableData: [], 64 search: '', 65 pageSize: 10, 66 pageSizes: [5, 10, 15, 20, 30, 40, 50], // select选项设置:条/页 67 currentPage: 1, 68 total: 0, 69 }, 70 created: function () { 71 this.getObsFilelist(); 72 73 }, 74 mounted: function () { 75 76 }, 77 methods: { 78 handleEdit(index, row) { 79 console.log(index, row); 80 }, 81 handleDelete(index, row) { 82 console.log(index, row); 83 }, 84 handleSizeChange(val) { 85 this.pageSize = val; 86 }, 87 handleCurrentChange(val) { 88 this.currentPage = val; 89 }, 90 getObsFilelist: function () { 91 var _this = this; 92 var entity = { 93 EntityId: _this.entityId, 94 EntityName: _this.entityName 95 }; 96 axios.post(_url, entity).then(function (response) { 97 console.log(response); 98 console.log(response.data); 99 if (response.data.code == 1) { 100 _this.tableData = response.data.data; 101 _this.total = response.data.data.length; 102 } 103 104 }).catch(function (error) { 105 console.log(error); 106 }); 107 //模拟数据 108 for (var i = 0; i < 120; i++) { 109 var obj = { 110 createdon: '2016-05-02', 111 foton_fileoldname: '测试obs文件' + i, 112 filetype: '类型' + i 113 }; 114 _this.tableData.push(obj); 115 } 116 _this.total = 120; 117 } 118 }, 119 }); 120 </script> 121 </body> 122 </html>