zoukankan      html  css  js  c++  java
  • vue2.0+Element UI 表格前端分页和后端分页

    之前写过一篇博客,当时对element ui框架还不太了解,分页组件用 html + css 自己写的,比较麻烦,而且只提到了后端分页 (见 https://www.cnblogs.com/zdd2017/p/9714633.html)。由于工作上的需要,写了很多表格,因此对于分页有了新的理解,在这里重新总结一下,用 element ui 自带的分页组件实现前端分页和后端分页。

    首先我们将分页功能的代码封装成一个组件,这样以后要用的时候可以直接拿,这里需要一个预备知识就是父子组件的交互,不清楚的可以自己先看一下。

    新建pagination.vue文件,内容如下:

    <template>
      <div :class="{'hidden':hidden}" class="pagination-container">
        <el-pagination
          :background="background"
          :current-page.sync="currentPage"
          :page-size.sync="pageSize"
          :layout="layout"
          :page-sizes.sync="pageSizes"
          :pager-count.sync="pageCount"
          :pager-count="pageCount"
          :total="total"
          v-bind="$attrs"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </template>
    
    <script>
    import { scrollTo } from "@/utils/scroll-to";
    
    export default {
      name: "Pagination",
      props: {
        total: {
          required: true,
          type: Number
        },
        page: {
          type: Number,
          default: 1
        },
        limit: {
          type: Number,
          default: 10
        },
        pageCount: {
          type: Number,
          default: 5
        },
        pageSizes: {
          type: Array,
          default() {
            return [10, 20, 30, 50];
          }
        },
        layout: {
          type: String,
          default: "total, sizes, prev, pager, next, jumper"
        },
        background: {
          type: Boolean,
          default: true
        },
        autoScroll: {
          type: Boolean,
          default: true
        },
        hidden: {
          type: Boolean,
          default: false
        }
      },
      computed: {
        currentPage: {
          get() {
            return this.page;
          },
          set(val) {
            this.$emit("update:page", val);
          }
        },
        pageSize: {
          get() {
            return this.limit;
          },
          set(val) {
            this.$emit("update:limit", val);
          }
        }
      },
      methods: {
        handleSizeChange(val) {
          this.$emit("pagination", { page: this.currentPage, limit: val });
          if (this.autoScroll) {
            scrollTo(0, 800);
          }
        },
        handleCurrentChange(val) {
          this.$emit("pagination", { page: val, limit: this.pageSize });
          if (this.autoScroll) {
            scrollTo(0, 800);
          }
        }
      }
    };
    </script>
    
    <style scoped>
    .pagination-container {
      background: #fff;
      padding: 32px 16px;
    }
    .pagination-container.hidden {
      display: none;
    }
    </style>

    新建父组件myTable.vue,引入pagination插件

    <el-table
          v-loading="listLoading"
          :key="tableKey"
          :data="list"
          border
          fit
          style=" 100%;"
        >
    <!--  表格内容省略 -->
    …………
    
    </el-table>
    
    <!-- 引入pagination插件 -->
    <pagination
          v-show="total>0"
          :total="total"
          :page.sync="listQuery.page"
          :limit.sync="listQuery.limit"
          @pagination="getList"
        />

    注册变量、方法

    export default {
        data() {
            return {
                list: null,
                total: 0,
                listQuery: {
                    page: 1,
                    limit: 10
                }
            }
        },
       created() {
    this.getList();
    } methods: {
    // 获取列表数据 getList() {} } }

    在首次进入页面, created 阶段以及每次点击页码时调用 getList() 方法,getList() 方法根据前端分页和后端分页的不同需求有不同写法。

    先看后端分页,后端分页比较简单,只要将当前页数 page 与每页显示条数 limit 传给后台,再把后台返回的数据赋值给list即可。

    getList() {
        axios.get('/list', {
            params: this.listQuery
        }).then(res => {
            this.list = res.value.list;
        })
    }

    前端分页一次性拿到所有数据,要根据 page 和 limit 以及 total 通过前端计算来决定每一页展示哪些数据,计算公式为

    this.list = res.value.list.slice((this.listQuery.page - 1) * this.listQuery.limit, this.listQuery.page * this.listQuery.limit);

    这里有一个问题,因为我们第一次请求就已经拿到了所有的数据,所以在每次点击页码时就没必要再发送请求。这里我们可以用一个变量alllist来缓存表格数据,然后每次点击页码时先检查alllist是否为空,为空则发送请求请求表格数据;不为空则不发送请求,直接拿alllist里的值来处理。

    在 data 里注册 alllist 变量后,getList() 方法如下:

    getList(pagination) {
          if (this.alllist) {
            if (pagination) {
              this.listQuery.page = pagination.page;
              this.listQuery.limit = pagination.limit;
            }
            this.list = this.alllist.slice(
              (this.listQuery.page - 1) * this.listQuery.limit,
              this.listQuery.page * this.listQuery.limit
            );
          } else {
            axios.get('/list', {
                params:  this.listQuery
            }).then(response => {
                this.alllist = response.value.list;
                this.total = response.value.list.length;
                this.list = this.alllist.slice(
                    (this.listQuery.page - 1) * this.listQuery.limit,
                    this.listQuery.page * this.listQuery.limit
                );
            });
          }
        }

    其中,pagination 参数只有在点击页码的时候才会由 pagination 组件通过触发 myTable 组件的 pagination 事件传递过来。

  • 相关阅读:
    C++-struct类的新特性当class用
    rbenv、fish 與 VSCode 設置之路
    angularJS进阶阶段(4)
    插入排序
    Vimium
    Design Patterns 25
    Mysql(或者sqlite), Mongo中update Column + 1
    Hexo
    继承
    Gradle的依赖方式——Lombok在Gradle中的正确配置姿势
  • 原文地址:https://www.cnblogs.com/zdd2017/p/11153527.html
Copyright © 2011-2022 走看看