background

The tables used in our project are generally similar, and if not encapsulated, each page might have some similar code. It is not only a waste of time, but also due to the different development habits of developers. It takes the maintenance staff a little time to look at everyone’s code. So I just made a secondary wrapper to the table, and only one person was needed to maintain the code. Here’s what I wrapped

Content:

1, support directly into the background request address rendering list, and parameters are modified after the automatic refresh 2, support to customize the display of each column 3, support according to the content of automatic support column width 4, support dynamic screening table head 5, support paging 6, shaking 7, column permissions... Try more on your ownCopy the code

Here is the code for the tableList component

<template> <! The refresh button and filter column should have control in the layout of the multi-select box, default display --> <div class="table">
    <div class="table-control" v-if="layoutKey.control">
      <div class="table-control-title" @click="reload">
        <i class="el-icon-refresh"></i></div>
      <el-dropdown class="table-control-title">
        <span class="el-dropdown-link"><i class="el-icon-s-operation table-control-icon"></i></span>
        <el-dropdown-menu slot="dropdown" class="table-control-checkbox">
          <el-checkbox-group v-model="headItems" @change="changeChecked">
            <el-checkbox class="table-control-checkbox-item"
                         v-for="(item,index) in allColumn"
                         :label="item"
                         :key="index">{{item}} </el-checkbox> </el-checkbox-group> </el-dropdown-menu> </el-dropdown> </div> <! -- List body --> <el-table class="table" style="width: 100%"
              ref="tableList"
              :data="tableData"
              :defaultSort.async="defaultSort"
              v-bind="$attrs"
              v-on="$listeners"
              @selectionChange="selectionChange"
              @sort-change="sortChange">
      <ex-table-column v-if="layoutKey.expand" type="expand" fixed>
        <slot name="expand" :data="props" slot-scope="props"/>
      </ex-table-column>
      <ex-table-column v-if="layoutKey.checkBox" fixed type="selection" :width="62"
                       :selectable="selectable"/>
      <ex-table-column v-if="layoutKey.index" type="index" label="Serial number" width="60"/>
      <ex-table-column v-for="(column,index) in activeColumn" :key="index"
                       :prop="column.field"
                       :column-key="column.field" :label="column.title" :fixed="column.fixed"
                       :sortable="column.sort" :selectable="column.selectable"
                       :show-overflow-tooltip="column.tooltip"
                       :autoFit='true' :width="column.width"
                       :fitByClass="autoWidth(column.width)"
                       :minWidth="column.minWidth || defaultWidth">
        <slot :name="column.field" :data="scope.row" :field="column.field" :content="column.field"
              :index="index" slot-scope="scope">
          <div>{{$utils.nvl(scope.row[column.field],The '-')}}</div> </slot> </ex-table-column> </el-table> <! -- <el-pagination background small class= --> <el-pagination background small class="table-pagination"
                   :current-page.sync="page.pageNo"
                   :page-sizes="page.list"
                   :page-size="page.pageSize"
                   :layout="page.layout" :total="page.total"
                   @current-change="handleCurrentChange"
                   @size-change="handleSizeChange" v-if="layoutKey.page"/>
  </div>
</template>

<script>
  import debounce from 'lodash/debounce';
  import ExTableColumn from './ExTableColumn';

  exportDefault {components: {ExTableColumn}, // provide this function for other components to callprovide() {
      return{ tableList: this, }; }, props: {// Default table size defaultWidth: {type: Number,
        required: false, default: 100,}, // Display the control, the current page,control two options, according to the need to expand the layout: {default:'page,control'}, // Return key with default id checkKey: {type: [Number, String],
        default: () => 'id'}, // Request parameters, mandatory req: {type: Object,
        required: true,
        default: () => ({
          url: undefined,
          type: 'post', params: {query: {},}, pageNo: 1, pageSize: 1,},}, // defaultSort, see elementUI table defaultSort: {type: [String, Object],
        required: false}, // display column // {title: mandatory String, display column name field: mandatory String, key width: optional, String column width, unit pixel, fixed: Parameter Description Value String Specifies whether the column is fixed. Optional Right, left sort: optional, Boolean specifies whether the column can be sorted. Expend: optional, Boolean specifies whether the slot can be expandedlimit: Optional, Boolean permission control,false} columns: {type: Array,
        required: true,
        default: () => [{ title: 'operation', field: 'ctrl', width: '60', fixed: 'right'}],}, // Check whether the CheckBox can be checked, see elementUI table selectable: {type: Function,
        default: () => true}, // all other table parameters are passed to table},data() {
      return {
        layoutKey: {},

        page: {
          list: [5, 10, 20, 50, 100],
          total: null,
          pageSize: 10,
          pageNo: 1,
          layout: 'total,sizes,prev,pager,next,jumper',
        },

        tableData: [],
        sort: ' ',
        checkRows: [],
        checkKeys: [],

        headItems: [],
        allColumn: [],
        activeColumn: [],
      };
    },

    methods: {
      sortChange({ prop, order }) {
        this.sort = `${prop} ${order === 'descending' ? 'desc' : 'asc'}`;
        this.refresh();
      },

      selectionChange(selection) {
        this.checkRows = selection;
        this.checkKeys = [];
        selection.map((row) => {
          this.checkKeys.push(row[this.checkKey]);
          return true;
        });
        this.$emit('selectionChange', selection); }, / * * * * * * * * * * * * * * * * * * * * * * * * * * * * method * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / / / paging async handleCurrentChange (currentPage) { this.page.pageNo = currentPage; this.$emit('handleCurrentChange', currentPage);
        await this.initTable({ vm: this });
      },

      handleSizeChange(size) {
        this.page.pageSize = size;
        this.page.pageNo = 1;
        this.$emit('handleSizeChange', size); this.initTable({ vm: this }); }, / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * dynamic rendering head * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / / / deselect the menuchangeChecked() {
        this.changeColumn({ vm: this });
      },
      changeColumn: debounce(async ({ vm }) => {
        const that = vm;
        const keys = new Set(vm.headItems);
        const activeColumn = vm.columns.filter((item) => {
          if (keys.has(item.title)) {
            return true;
          }
          return false; }); that.activeColumn = activeColumn; that.activeColumn.splice(1, 0); }, 200), / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * refresh * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * / / / refresh the table data (using the existing parameter) refresh (type) {
        if (type= = ='delete'&& this.page.pageNo > 1 && this.tableData.length === 1) { this.page.pageNo = this.page.pageNo - 1; } this.initTable({ vm: this }); }, // reload data (reset to first page)reload() {
        if(this.page.pageNo ! == 1) { this.page.pageNo = 1; } this.initTable({ vm: this }); }, initTable: debounce(async ({ vm }) => { const that = vm; that.tableData = []; const params = that._.assign({ pageNo: that.page.pageNo, pageSize: that.page.pageSize, sortStr: that.sort }, that.req.params); / / right value to cover the left value, returns an lvalue / / initiate the request, according to the practical projects, the interface for const {data} = await window. Axios [that. The req. Type | |'post'](that.req.url, params);
        if (data && that.$utils.Type.isArray(data.result)) {
          that.tableData = data.result;
          that.page.total = data.total * 1;
        }
        that.$nextTick(() => {
          that.$emit('loadDone', that.tableData, params);
        });
      }, 300),

      getCheckRows() {
        return this.checkRows;
      },

      getCheckKeys() {
        return this.checkKeys;
      },

      handleHead(columns) {
        const allColumn = [];
        columns.map((item) => {
          if(! item.limit) { allColumn.push(item.title); }return true;
        });
        this.headItems = allColumn;
        this.allColumn = allColumn;
        this.changeChecked();
      },

      handleLayout() {
        const layout = this.layout;
        if(! layout)return null;
        layout.split(', ')
        .map(
          (item) => {
            const key = item.trim();
            this.layoutKey[key] = true;
            return true; });return this.layoutKey;
      },

      autoWidth(width) {
        if (this.$utils.isEmpty(width)) {
          return 'cell';
        }
        return width;
      },

      init() {
        this.handleLayout();
        this.handleHead(this.columns);
        if (this.defaultSort) {
          const { prop, order } = this.defaultSort;
          this.sort = `${prop} ${order === 'descending' ? 'desc' : 'asc'}`;
        }
        this.initTable({ vm: this });
      }
      ,
    },
    async created() {
      this.init();
    },

    watch: {
      queryParams: {
        handler() {
          this.reload({ vm: this });
        },
      },
      columns: {
        handler() {
          this.handleHead(this.columns);
        },
      },
    },
    computed: {
      queryParams() {
        if (this.$utils.isNotEmpty(this.req.params)) {
          return this.req.params;
        }
        return{}; ,}}}; </script> <style lang="less" scoped>
  @import './style/index';
</style>
Copy the code

Method of use

<template>
  <div>
    <table-list
      :req="tableReq"
      ref="tableList"
      :stripe="true"// Table's original arguments are also supported. Methods are also supported. :columns="[{title: 'user name' field: 'name', sort: 'true', fixed: true}, {title: 'English name' field: 'aliasName, sort:' true ', fixed: true}. {title: 'age', field: 'age, sort: true}, {title:' professional ', the field: 'job', sort: true}, {title: 'email' field: 'email'}, {the title: 'date of birth, field:' birthday '}, {title: 'home address' field: 'address'}, {title: 'hukou' field: 'domicile'},]"> <! -- Format the time column, all columns can be used this way, slot name column field--> <template slot="birthday" slot-scope="{data}">
        <span>{{format(data.birthday)}}</span>
      </template>
    </table-list>
  </div>
</template>

<script>
  import TableList from './table/components/TableList';

  export default {
    name: 'HelloWorld',
    components: { TableList },
    data() {
      return {
        tableReq: {
          url: '/user/list'/ / requiredtype: 'post'// Optional, default post params: {} // Optional}}; }, methods: { format(time) {if (this.$utils.isEmpty(time)) return '/';
        return this.$utils.format(new Date(time), 'yyyy-MM-dd HH:mm'); }},mounted() {}}; </script>Copy the code

Here’s how it looks