The secondary encapsulation of antd table implements the functions of zebra pattern, column display and hiding, paging, dragging to change column width and slot to operate columns.

Main code: 

html:

<template>
  <div>
    <div style="text-align: right; padding-bottom: 5px">
      <a-popover title="请选择要展示的列" placement="topRight">
        <template slot="content">
          <a-checkbox
            v-for="c in tHead"
            :key="c.title"
            @change="onCheckChange"
            :defaultChecked="true"
            :value="c.title"
          >
            {
   
   { c.title }}
          </a-checkbox>
        </template>
        <a class="ant-dropdown-link" @click="(e) => e.preventDefault()">
          筛选列 <a-icon type="down" />
        </a>
      </a-popover>
    </div>
    <a-table
      :loading="loading_"
      class="tbBorder"
      :rowSelection="rowSelection"
      :rowKey="rowKey"
      :pagination="pagination_"
      :dataSource="dataSource_"
      :components="components_"
      v-bind="$props"
      v-on="$listeners"
      :columns="columns_"
      @change="handleTableChange"
      size="middle"
      :scroll="{ x: scrollX || 0 }"
      :rowClassName="
        (record, index) => {
          if (index % 2 != 0) return 'stripe';
        }
      "
    >
      <template
        v-for="column in columns"
        :slot="column.scopedSlots ? column.scopedSlots.customRender : ''"
        slot-scope="text, record"
      >
        <slot
          :name="column.scopedSlots ? column.scopedSlots.customRender : ''"
          v-bind:scope="record"
        ></slot>
      </template>
    </a-table>
  </div>
</template>

js:

<script>
import { Table } from "ant-design-vue";
import VueDraggableResizable from "vue-draggable-resizable";
import { mapState } from "vuex";

export default {
  components_: {
    VueDraggableResizable,
  },
  props: {
    ...Table.props,
    api: { type: String },
    queryParams: { type: Object },
    get: { type: Boolean },
    rowKey: { type: String },
    scrollX: { type: Number },
    rowSelection: { type: Object },
  },
  data() {
    this.components_ = {
      header: {
        cell: (h, props, children) => {
          const { key, ...restProps } = props;
          const col = this.columns.find((col) => {
            const k = col.dataIndex || col.key;
            return k === key;
          });

          if (!col || !col.width) {
            return h("th", { ...restProps }, [...children]);
          }
          if (props.key == "operation") {
            return h("th", { ...restProps, class: "operation" }, [...children]);
          }

          const dragProps = {
            key: col.dataIndex || col.key,
            class: "table-draggable-handle",
            attrs: {
              w: 10,
              x: col.width,
              z: 1,
              axis: "x",
              draggable: true,
              resizable: false,
            },
            on: {
              dragging: (x, y) => {
                col.width = Math.max(x, 1);
              },
            },
          };
          const drag = h("vue-draggable-resizable", { ...dragProps });

          return h("th", { ...restProps, class: "resize-table-th" }, [
            ...children,
            drag,
          ]);
        },
      },
    };
    return {
      selectedRowKeys: [],
      selectedRows: [],
      columns_: this.columns,
      tHead: [],
      dataSource_: [],
      loading_: false,
      pagination_: this.pagination || {
        total: 0,
        pageSizeOptions: ["10", "20", "30", "40", "100"],
        current: 1,
        defaultPageSize: 10,
        showQuickJumper: false,
        showSizeChanger: true,
        showTotal: (total, range) =>
          `显示 ${range[0]} ~ ${range[1]} 条记录,共 ${total} 条记录`,
      },
    };
  },

  mounted() {
    this.tHeadCreat(this.columns);
    this.fetch();
  },
  methods: {
    tHeadCreat(columns) {
      columns.forEach((ele) => {
        if (columns.indexOf(ele) != columns.length - 1) {
          ele.colSpan = 1;
          this.tHead.push(ele);
        }
      });
    },
    //筛选列
    onCheckChange(e) {
      this.tHead.map((ele) => {
        if (ele.title === e.target.value) {
          ele.colSpan = e.target.checked ? 1 : 0;
          this.changeColumns(e.target.value, e.target.checked);
        }
      });
    },
    changeColumns(title, checked) {
      if (checked) {
        let i = 0; //用来标记插入时的位置,从头开始找
        this.tHead.forEach((ele, index) => {
          if (ele.title != title) {
            if (
              this.columns_.some((item) => {
                return item.title == ele.title;
              })
            ) {
              i++; //如果该元素已经存在则向后移动一位
            }
          } else {
            this.columns_.splice(i, 0, ele);
          }
        });
      } else {
        this.columns_.map((ele, index) => {
          if (ele.title == title) {
            this.columns_.splice(index, 1);
          }
        });
      }
    },

    //分页
    handleTableChange(pagination, filters, sorter) {
      this.pagination_ = pagination;
      this.fetch();
    },
    resetPagination() {
      this.pagination_.current = 1;
    },
    fetch(p) {
      let param = p || this.queryParams;
      this.loading_ = true;
      if (this.get) {
        this.$get(this.api, {
          ...param,
          pageSize:
            this.pagination_.pageSize || this.pagination_.defaultPageSize,
          pageNum: this.pagination_.current,
        })
          .then((res) => {
            console.log("res-get", res);
            let data = res.data;
            this.pagination_.total =
              data.total == undefined ? data.length : data.total;
            this.dataSource_ = data.rows.children || data.rows || data;
            this.loading_ = false;
          })
          .catch((err) => {
            console.warn(err);
          });
      } else {
        this.$post(this.api, {
          ...param,
          pageSize: this.pagination_.pageSize,
          pageNum: this.pagination_.current,
        })
          .then((res) => {
            console.log("dataTable-res", res);
            let data = res.data;
            this.pagination_.total =
              data.total == undefined ? data.length : data.total;
            if (data.rows) {
              if (data.rows.children) this.dataSource_ = data.rows.children;
              else this.dataSource_ = data.rows;
            } else this.dataSource_ = data;
            //  this.dataSource_ = data.rows.children || data.rows || data;
            this.loading_ = false;
          })
          .catch((err) => {
            console.warn(err);
          });
      }
    },
  },
};
</script>

css style

<style lang="less">
.table-draggable-handle {
  /* width: 10px !important; */
  height: 100% !important;
  left: auto !important;
  right: -5px;
  cursor: col-resize;
  touch-action: none;
  border: none;
  position: absolute;
  transform: none !important;
  bottom: 0;
}
.resize-table-th {
  position: relative;
}
.tbBorder {
  border: 1px solid #ebebeb;
}
// .stripe {
//   background-color: #fafafa;
// }
.ant-table-scroll {
  .operation {
    color: transparent;
  }
}
</style>

 Code when referenced by parent component:

<my-table
      ref="dataTable"
      api="user"
      :get="true"
      :rowKey="'userId'"
      :columns="columns"
      :queryParams="queryParams"
      :rowSelection="{
        selectedRowKeys: selectedRowKeys,
        onChange: onSelectChange,
      }"
      :scrollX="1450"
    >
      <template slot="operation" slot-scope="record">
        <a-button
          type="link"
          class="btn-operation"
          v-hasPermission="'user:update'"
          @click="edit(record.scope)"
          >修改</a-button
        >
        <a-button
          type="link"
          class="btn-operation"
          v-hasPermission="'user:update'"
          @click="view(record.scope)"
          >查看</a-button
        >
        <a-button
          type="link"
          class="btn-operation"
          v-hasPermission="'user:update'"
          @click="resetPassword(record.scope)"
          >密码重置</a-button
        >
      </template>
    </my-table>

Guess you like

Origin blog.csdn.net/zhuangjiajia09/article/details/122090902