vue+typescript二次封装element-ui的table表格

vue+typescript二次封装element-ui的table表格_第1张图片
app-pagination.vue

<template>
  <div class="app-pagination" :style="rootStyle">
    <el-pagination
      :page-sizes="pageSizes"
      :layout="layout"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    ></el-pagination>
  </div>
</template>

<script lang="ts">
import { Component, Vue, Prop, Watch, Emit } from "vue-property-decorator";
import { State, namespace } from "vuex-class";

interface IModuleData {
  current_page: number;
  total: number;
}

@Component
export default class AppPagination extends Vue {
  @Prop({ type: Boolean, default: false }) readonly useModuleData!: boolean;
  @Prop({ type: Object, default: () => {} }) readonly moduleData!: IModuleData;
  @Prop({ type: Number, default: 1 }) readonly currentPage!: number;
  @Prop({ type: Number, default: 0 }) readonly total!: number;
  @Prop({ type: Number, default: 20 }) readonly pageSize!: number;
  @Prop({ type: Array, default: () => [20, 50, 100] })
  readonly pageSizes!: number[];
  @Prop({ type: String, default: "total, sizes, prev, pager, next, jumper" })
  readonly layout!: string;
  //修改当前页大小的Mutation
  @Prop({ type: Function, default: null }) readonly mutationCurrentPageSize;
  //修改当前页的Mutation
  @Prop({ type: Function, default: null }) readonly mutationCurrentPage;
  //获取当前页数据的Action
  @Prop({ type: Function, default: null }) readonly actionCurrentPage;

  rootStyle: object = {};

  handleSizeChange(curSize) {
    this.$emit("size-change", curSize);
    this.mutationCurrentPageSize && this.mutationCurrentPageSize(curSize);
    this.mutationCurrentPage && this.mutationCurrentPage(1);
    this.actionCurrentPage && this.actionCurrentPage();
  }
  handleCurrentChange(curPage) {
    console.log(curPage);
    this.$emit("current-change", curPage);
    this.mutationCurrentPage && this.mutationCurrentPage(curPage);
    this.actionCurrentPage && this.actionCurrentPage();
  }
  // get getCurrentPage() {
  //   return this.useModuleData
  //     ? this.$get(this.moduleData, "current_page", 1)
  //     : this.currentPage;
  // }

  // get getPageSize() {
  //   return this.useModuleData
  //     ? this.$get(this.moduleData, "page_size", 20)
  //     : this.pageSize;
  // }

  // get getTotal() {
  //   return this.useModuleData
  //     ? this.$get(this.moduleData, "total", 0)
  //     : this.total;
  // }
}
</script>

<style lang="scss">
.app-pagination {
  display: flex;
  align-items: center;
  width: 100%;
  height: $--page-bottom;
  padding-right: 4px;
  text-align: right;
  .el-pagination {
    width: 100%;
    .btn-prev,
    .btn-next,
    .el-pager li {
      background-color: transparent;
    }
  }
}
</style>

column-render.js

export default {
    name: 'ColumnRender',
    props: {
        renderCol: Function,
        record: Object,
        value: [String, Number],
        index: Number
    },

    render(h) {
        let _self = this;
        return _self.renderCol.call(
            this._renderProxy,
            h,
            {
                text: _self.value,
                record: _self.record,
                $index: _self.index,
                align: _self.center
            }
        );
    }
};

index.ts

import Table from './table.vue'
export default Table

table.vue

<template>
  <div :class="['component-table', 'standardTable']">
    <div :class="[{ table_border: border }]">
      <el-table
        ref="commonTable"
        v-loading="loading"
        v-bind="$attrs"
        :height="height"
        border
        :stripe="stripe"
        v-on="$listeners"
      >
        <el-table-column
          v-if="selectable"
          type="selection"
          fixed
          :width="60"
          :selectable="selectableFunction"
          :show-overflow-tooltip="true"
          align="center"
        ></el-table-column>
        <el-table-column
          v-if="indexed"
          type="index"
          fixed
          :width="60"
          label="序号"
          align="center"
          :show-overflow-tooltip="true"
        ></el-table-column>
        <el-table-column
          v-if="isRadio"
          :width="100"
          label="请选择"
          align="center"
          :show-overflow-tooltip="true"
        >
          <!-- //--- 单选框这里取到当前单元格 -->
          <!-- //--- scope.$index 直接取到该单元格值 -->
          <template slot-scope="scope">
            <el-radio v-model="radio" class="radio" :label="scope.$index">&nbsp;</el-radio>
          </template>
        </el-table-column>
        <template v-for="item in columns">
          <el-table-column
            v-if="item.render"
            :key="item.dataIndex"
            v-bind="item"
            :show-overflow-tooltip="true"
          >
            <template slot-scope="{ row, column, $index }">
              <column-render
                :render-col="item.render"
                :record="row"
                :value="row[item.dataIndex]"
                :index="$index"
                :align="item.align"
              ></column-render>
            </template>
          </el-table-column>
          <el-table-column v-else :key="item.prop" v-bind="item" :show-overflow-tooltip="true"></el-table-column>
        </template>
        <slot></slot>
      </el-table>
    </div>
    <app-pagination v-if="hasPagination" v-bind="$attrs" v-on="$listeners"></app-pagination>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from "vue-property-decorator";
import ColumnRender from "./column-render";
import AppPagination from "./app-pagination.vue";

@Component({
  components: {
    ColumnRender,
    AppPagination
  }
})
export default class BaseTable extends Vue {
  @Prop({
    type: Array,
    default: () => []
  })
  readonly columns!: any[];
  @Prop({
    type: Boolean,
    default: true
  })
  readonly indexed!: boolean;
  @Prop({
    type: Boolean,
    default: true
  })
  readonly selectable!: boolean;
  @Prop({
    type: Boolean,
    default: false
  })
  readonly isRadio!: boolean;
  @Prop({
    type: Boolean,
    default: false
  })
  readonly loading!: boolean;
  @Prop({
    type: [Number, String],
    default: "100%"
  })
  readonly height!: number | string;
  @Prop({
    type: Function,
    default: () => {
      return true;
    }
  })
  readonly selectableFunction!: Function;
  @Prop({
    type: Function,
    default: null
  })
  readonly render!: Function;
  @Prop({
    type: Boolean,
    default: false
  })
  readonly stripe!: boolean;
  @Prop({
    type: Boolean,
    default: true
  })
  readonly border!: boolean;
  @Prop({
    type: Boolean,
    default: false
  })
  readonly hasPagination!: boolean;
  @Prop({
    type: Boolean,
    default: true
  })
  readonly showHeader!: boolean;
  radio: string = "-1";
  clearSelection() {
    (this.$refs.commonTable as any).clearSelection();
  }

  clearSort() {
    (this.$refs.commonTable as any).clearSort();
  }
}
</script>
<style lang="scss" scoped>
/deep/.search-table .component-table .el-table tr {
  height: 40px !important;
}
</style>
<style lang="scss">
.component-table.standardTable {
  width: 100%;
  height: 100%;
  overflow: auto;
  > div {
    height: 100%;
  }
  .el-table th.gutter {
    display: table-cell !important;
  }
  .el-table--small td,
  .el-table--small th {
    padding: 0;
  }
  .el-table__header {
    tr {
      height: 38px;
    }
    // .caret-wrapper {
    //   height: 23px;
    //   .sort-caret {
    //     border: 4px solid transparent;
    //   }
    // }
  }
  .row {
    height: 32px;
  }
  .pagination {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 100%;
  }
}
</style>

父组件引用

import vTable from "@/components/table";
 <v-table
        ref="vtable"
        v-loading="loading"
        class="right-table-tree"
        :row-key="getRowKey"
        :indexed="false"
        :data="tableData"
        :columns="columns"
        lazy
        :load="load"
        :tree-props="{ children: 'children', hasChildren: 'hasChild' }"
        @selection-change="selectionChange"
        v-bind="$attrs"
        v-on="$listeners"
      ></v-table>

绑定数据

 columns: any[] = [
    {
      label: "序号",
      prop: "orderNum",
      minWidth: "12%"
    },
    {
      label: "编号",
      prop: "code",
      minWidth: "12%"
    },
    {
      label: "统计顺序码",
      prop: "showorder",
      minWidth: "13%"
    },
    {
      label: "名称",
      prop: "name",
      minWidth: "53%"
    },
    {
      label: "状态",
      prop: "enabled",
      minWidth: "10%"
    }
  ];

tableData请求接口数据

你可能感兴趣的:(vue+typescript二次封装element-ui的table表格)