基于element-ui的 分页表格组件

约定不等于承诺〃 2023-10-06 07:22 77阅读 0赞

文章目录

  • 实现思路
  • 组件代码
  • 使用案例
  • 系列文章

实现思路

搜索网上的分页表格案例,大部分是使用for循环来渲染表格列,那样只能支持纯展示的数据,对于需要特殊处理的字段无法支持(eg:案例中的’状态’列,需要将状态码转换成中文)。
为了解决这个问题,使用了插槽特性 (了解一下插槽)。

基于组件化思想,利用elemeut-ui 的 <el-table><el-pagination> 封装一个前端分页表格组件。使用方式基本和<el-table> 一样,组件样式大家看着调。

组件功能

  1. 分页功能开关
  2. 支持前端分页
  3. 支持分页参数的设置

效果图
在这里插入图片描述

组件代码

代码稍长,必要的注释都注明在代码中,文末附使用案例。建议先跑起来使用案例看效果,再深入代码。
代码上传在 前端代码在线编辑器codesandbox 中,可直接查看编辑:此链接

了解下 codesanbox

  1. <template>
  2. <el-container class="page-table-ctn">
  3. <el-table v-bind="$attrs" v-on="$listeners" :data="filterData" ref="pageTable">
  4. <slot></slot>
  5. </el-table>
  6. <el-footer class="footer" v-if="paging">
  7. <div class="size-info">
  8. <span v-if="totalSize > 1">显示第 {
  9. {
  10. start}} 条到第 {
  11. {
  12. end}} 条的数据,</span>
  13. 共{
  14. {
  15. totalSize }} 条数据
  16. </div>
  17. <el-pagination
  18. v-bind="$attrs"
  19. v-on="$listeners"
  20. :pager-count="5"
  21. :layout="layout"
  22. :page-sizes="pageSizes"
  23. :page-size="currPageSize"
  24. :current-page="currPage"
  25. :total="totalSize"
  26. style="float:right"
  27. @current-change="handleCurrentChange"
  28. @size-change="handleSizeChange"
  29. ></el-pagination>
  30. </el-footer>
  31. </el-container>
  32. </template>
  33. <script>
  34. export default {
  35. name: "page-table",
  36. props: {
  37. data: {
  38. type: Array,
  39. require: true,
  40. default: []
  41. },
  42. currentPage: {
  43. type: Number,
  44. default: 1
  45. },
  46. pageSize: {
  47. type: Number,
  48. default: 10
  49. },
  50. pageSizes: {
  51. type: Array,
  52. default: () => [10, 30, 50, 100]
  53. },
  54. layout: {
  55. type: String,
  56. default: "sizes, prev, pager, next, jumper"
  57. },
  58. // 是否分页,默认为true,即分页。(不分页时将每页条数设置最大。)
  59. paging: {
  60. type: Boolean,
  61. default: true
  62. }
  63. },
  64. data() {
  65. return {
  66. allData: this.data, // 全量表格数据(前端分页)
  67. filterData: [], // 表格展示数据
  68. start: 1,
  69. end: 1,
  70. totalSize: this.data.length,
  71. currPageSize: this.paging ? this.pageSize : Number.MAX_SAFE_INTEGER,
  72. currPage: this.currentPage
  73. };
  74. },
  75. methods: {
  76. handleSizeChange(value) {
  77. this.currPage = 1;
  78. this.currPageSize = value;
  79. this.handleChange();
  80. },
  81. handleCurrentChange(value) {
  82. this.currPage = value;
  83. this.handleChange();
  84. },
  85. handleChange(reset) {
  86. // reset:是否重置页码
  87. if (reset) {
  88. this.currPage = 1;
  89. }
  90. this.renderTable();
  91. },
  92. renderTable() {
  93. if (this.totalSize > this.currPageSize) {
  94. // 总行数大于一页
  95. let startIndex = (this.currPage - 1) * this.currPageSize,
  96. endIndex = this.currPage * this.currPageSize;
  97. this.start = startIndex + 1;
  98. this.end = this.totalSize < endIndex ? this.totalSize : endIndex;
  99. this.filterData = this.allData.slice(startIndex, endIndex); //[start,end)
  100. } else if (this.totalSize > 0) {
  101. // 总行数小于等于一页
  102. this.currPage = 1;
  103. this.start = 1;
  104. this.end = this.totalSize;
  105. this.filterData = this.allData;
  106. } else {
  107. // 无数据
  108. this.currPage = 1;
  109. this.start = 0;
  110. this.end = 0;
  111. this.filterData = [];
  112. }
  113. },
  114. setData(value) {
  115. this.allData = value;
  116. this.totalSize = value.length;
  117. this.renderTable();
  118. },
  119. //<el-table>自带的方法 start
  120. setCurrentRow(row) {
  121. this.$refs.pageTable.setCurrentRow(row);
  122. }
  123. //...
  124. //<el-table>自带的方法 end
  125. },
  126. watch: {
  127. data() {
  128. this.setData(this.data ? this.data : []);
  129. }
  130. },
  131. mounted() {
  132. }
  133. };
  134. </script>
  135. <style lang="scss" scoped>
  136. .page-table-ctn {
  137. > .el-table {
  138. width: auto;
  139. margin: 14px;
  140. border: 1px solid #ebeef5;
  141. border-bottom: unset;
  142. }
  143. > .footer {
  144. height: 40px !important;
  145. .size-info {
  146. display: inline;
  147. font-size: 12px;
  148. color: #666666;
  149. }
  150. }
  151. }
  152. </style>

使用案例

  1. <template>
  2. <div>
  3. 前端分页案例:
  4. 1.设置表格数据
  5. <PageTable
  6. :data="tableData"
  7. :currentPage=2
  8. :pageSizes="[3,5,10]"
  9. :pageSize=5
  10. :paging=true
  11. ref="dataTable"
  12. >
  13. <el-table-column type="selection" width="55"></el-table-column>
  14. <el-table-column label="账号" prop="name"></el-table-column>
  15. <el-table-column label="名称" prop="nickname"></el-table-column>
  16. <el-table-column label="邮箱" prop="email"></el-table-column>
  17. <el-table-column label="状态">
  18. <template slot-scope="scope">{
  19. {
  20. scope.row.state%2===0?'正常':'锁定' }}</template>
  21. </el-table-column>
  22. <el-table-column label="操作" width="100">
  23. <template slot-scope="scope">
  24. <el-button size="small" type="text" @click.stop="clickFunc(scope.row)">操作按钮</el-button>
  25. </template>
  26. </el-table-column>
  27. </PageTable>
  28. </div>
  29. </template>
  30. <script>
  31. // 引入表格组件
  32. import PageTable from "./PageTable.vue";
  33. export default {
  34. components: {
  35. PageTable // 引用表格组件
  36. },
  37. data() {
  38. return {
  39. tableData: []
  40. };
  41. },
  42. methods: {
  43. queryData() {
  44. // 模拟后台数据
  45. let data = [];
  46. for (var i = 1; i <= 23; i++) {
  47. data.push({
  48. name: i, nickname: i, email: i, state: i });
  49. }
  50. this.tableData = data;
  51. },
  52. clickFunc(row) {
  53. // console.log(row);
  54. alert(JSON.stringify(row));
  55. }
  56. },
  57. mounted() {
  58. // 发起查询请求
  59. this.queryData();
  60. }
  61. };
  62. </script>
  63. <style lang="scss" scoped>
  64. </style>

系列文章

  • 分页表格组件
  • 动态列分页表格组件(动态控制表格列的显隐)
  • 后端分页表格组件
  • 终极分页表格组件(前/后端分页、动态列)

end

发表评论

表情:
评论列表 (有 0 条评论,77人围观)

还没有评论,来说两句吧...

相关阅读