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 事件传递过来。

  • 相关阅读:
    MS CRM 2011的自定义和开发(10)——CRM web服务介绍(第一部分)——IDiscoveryService
    MS CRM 2011的自定义和开发(7)——视图编辑器(第二部分)
    MS CRM 2011 SDK 5.06版本已经发布
    MS CRM 2011的自定义和开发(11)——插件(plugin)开发(一)
    近来遇到的MS CRM 2011方面的几个问题
    MS CRM 2011的自定义与开发(6)——表单编辑器(第二部分)
    Microsoft Dynamics CRM 2011中,Lookup字段的赋值
    MS CRM 2011的自定义和开发(6)——表单编辑器(第三部分)
    Visual Studio 目标框架造成 命名空间“Microsoft”中不存在类型或命名空间名称“Crm”。是否缺少程序集引用中错误的处理
    一步步学习Reporting Services(二) 在报表中使用简单的参数作为查询条件
  • 原文地址:https://www.cnblogs.com/zdd2017/p/11153527.html
Copyright © 2011-2022 走看看