如何使Element的表格和分页擦出爱的火花

1,306 阅读3分钟

一.前言。

之前讲述过如今的项目开发场景,涉及到列表需求的时候,大多都是使用表格(el-table)分页(el-pagination) 相结合实现,也就是前端处理页码和当前页发起请求,后端提供对应的数据,本文就以种效果为目的讲述如何优雅高效地实现它。当然,极少数情况下,是后端一次性返回所有的数据,由前端自行处理分页 ---- 这部分可参考我的另一篇文章 纯前端分页,这里不在作累述 。

二.封装通用的表格js(混入mixins实现)。

  • 说明:src文件夹下创建mixins文件夹,并在其内创建table.js文件作为通用表格的mixins。之后即可在具体业务列表组件中import引入相对应的混入js文件 最后通过 mixins: [table]来使用。

  • 核心代码:

  1. table.js:
export default {
    data() {
        return {
            tableData: [],    //用于存储列表的数据
            tableHeight: '500', //列表的初始高度
            currentPage: 1,    //当前页
            pageSize: 20,   //每页的容量
            total: 0,   //列表总数
            loading: false, //列表的数据加载loading状态
        }
    }
}
  1. 具体的业务列表组件:
import table from "mixins/table";

mixins: [table],

三.表格(el-table)和分页(el-pagination)结合。

  • 说明:整合表格(el-table)和分页(el-pagination)的特性及对应的API,结合混入(mixins)中的table.js文件定义的tableDatapageSize等变量实现业务组件的完美数据展示和翻页等操作实时拉取对应的数据。(ps:当然,各自业务场景的参数还是和后端童靴一同商讨好,随之改动即可)。

  • 核心代码:

  1. 具体业务列表组件:
<template>
  <div class="h-p-100">
    <div class="g-page-title clearfix">
      <p>{{ $route.meta.title }}</p>
      <div class="f-r">
        <el-button @click="getWorkOrderList()">刷新</el-button>
      </div>
    </div>
    <div class="f-l p-card-info-wrap" style="width: 100%">
      <div class="g-table-header">
        <el-input
          v-model.trim="search.sn"
          clearable
          placeholder="请输入编号"
          class="w-230 umar-r10 umar-b10"
        ></el-input>
        <el-button type="primary" class="umar-b10" @click="getWorkOrderList(1)"
          >查询</el-button
        >
        <el-button type="success" class="umar-b10" @click="handleReset"
          >重置</el-button
        >
      </div>
      <div class="g-table-content">
        <el-table
          :data="tableData"
          :height="tableHeight"
          border
          header-cell-class-name="g-table-header-cell"
          :highlight-current-row="true"
          v-loading="loading"
        >
          <el-table-column
            prop="id"
            label="ID"
            min-width="120"
            show-overflow-tooltip
          >
          </el-table-column>
          <el-table-column
            prop="sn"
            label="编号"
            min-width="180"
            show-overflow-tooltip
          >
          </el-table-column>
          </el-table-column>
          <el-table-column label="状态" min-width="100">
            <template slot-scope="{ row }">
              <div v-if="row.status == 2" style="color: green">已确认</div>
              <div v-else style="color: red">未确认</div>
            </template>
          </el-table-column>
          <el-table-column
            prop="createTime"
            label="创建时间"
            min-width="180"
            show-overflow-tooltip
          >
          </el-table-column>
          <el-table-column label="操作" min-width="120" fixed="right">
            <template slot-scope="{ row }">
              <span
                class="g-table-btn"
                @click="handleClose(row)"
                v-if="row.status != 2"
                ><i class="icon iconfont el-icon-switch-button"></i
                >确认</span
              >
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div class="g-table-page clearfix">
        <el-pagination
          class="f-r uinn-tb10"
          layout="total, sizes, prev, pager, next, jumper"
          :page-sizes="[20, 100, 200, 500]"
          :page-size="pageSize"
          :current-page="currentPage"
          :total="total"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        >
        </el-pagination>
      </div>
    </div>
  </div>
</template>
<script>
import table from "mixins/table";
import * as API from "api/inter_expir_reminder/inter_expir_reminder";
export default {
  mixins: [table],
  data() {
    return {
      search: {
        sn: "",
      },
    };
  },
  watch: {},
  mounted() {
    this.init();
  },

  methods: {
    init() {
      this.getWorkOrderList();
    },
    //获取列表数据
    getWorkOrderList(currentPage = this.currentPage) {
      this.loading = true;
      let data = new URLSearchParams();
      for (let i in this.search) {
        if (this.search[i]) {
          data.append(i, this.search[i]);
        }
      }
      data.append("current", currentPage);
      data.append("size", this.pageSize);
      API.getJkList(data)
        .then((res) => {
          this.loading = false;
          if (res.code == 200) {
            this.tableData = res.data;
            this.total = res.total;
            this.currentPage = currentPage;
          }
        })
        .catch((err) => {
          this.loading = false;
        });
    },
    //重置
    handleReset() {
      for (let i in this.search) {
        this.search[i] = "";
      }
      this.getWorkOrderList();
    },
    //切换当前页的容量
    handleSizeChange(val) {
      this.pageSize = val;
      this.getWorkOrderList(1);
    },
    //翻页
    handleCurrentChange(val) {
      this.currentPage = val;
      this.getWorkOrderList();
    },
    //操作
    handleClose(row) {
      console.log(row);
    },
  },
};
</script>
  • 效果展示:

GIF.gif

四.细节处理(删除等操作)

  1. 删除操作:
  • 说明:列表中的删除操作在请求删除接口成功后都是需要重新刷新下当前列表,除了这样,为了做到更完美的人性化效果,就应该在删除操作中考虑到所删除的当前行是不是当前页的最后一条(如果是,那么得回到上一页),还有就是要考虑到当前页是不是第一页(直接刷新第一页)。

  • 案例及核心代码图示:

image.png

image.png

image.png

  1. 修改、编辑、启用、禁用等操作:
  • 说明:列表中的修改、编辑、启用、禁用等操作在请求对应的接口成功后需要重新刷新列表并保持在操作前的所在页,这样才能保证数据的准确性及操作人性化。

  • 案例及核心代码图示:

image.png

  • 解析:这就是为什么我们在请求列表数据的方法中设置了默认值及赋值为当前页了。就是为了结合各种操作下的列表数据和页面实时对上,提升人性化和操作性。

image.png

五.结语。

相信通过以上简述和方案,以后在遇到列表需求时,童靴们不仅只是单纯地做出简单的数据列表展示,而是能尽可能地考虑到用户的操作和人性化体验。这样才能完美地让Element的表格(el-table)和分页(el-pagination)擦出爱的火花