ts二次封装element-ui的table表格,带loading,分页

新建文件tablePage.vue

<template>
    <div id="table_page">
        <el-table 
            ref="vtable" 
            v-loading="loading"
            @row-click="rowClick" 
            @select="select" 
            @select-all="select" 
            @current-change="rowChange"
            @selection-change="handleSelectionChange"
            :data="data" 
            size="mini" 
            stripe 
            style="width: 100%" 
            highlight-current-row 
            :header-cell-style="headerStyle" 
            :cell-style="cellStyle" 
            :row-style="rowStyle"
        >
            <el-table-column 
                v-if="selection"
                type="selection"
                width="55">
            </el-table-column>
            <template v-for="(item,index) in column">
				<el-table-column 
					v-if="!item.slot" 
					:key="index" 
					:prop="item.prop" 
					:width="item.width" 
					:label="item.label" 
					:align="item.align || 'center'" 
                    :fixed="item.fixed"
                >
				</el-table-column>
				<el-table-column 
					v-if="item.slot" 
					:key="index" 
					:label="item.label" 
					:prop="item.prop" 
					:width="item.width" 
                    :fixed="item.fixed"
					:align="item.align || 'center'">
					<template #default="{ row, $index }">
						<slot :name="item.slot" :index="$index" :row="row" :value="row[item.prop]" :prop="item.prop"></slot>
					</template>
				</el-table-column>
			</template>
        </el-table>
        <el-pagination
            v-if="page"
            @current-change="handleCurrentChange"
            layout="total, prev, pager, next"
            :current-page.sync="page.PageIndex"
			:total="page.PageTotal" 
			:page-size="page.PageSize">
        </el-pagination>
    </div>
</template>

<script lang="ts">
import { Component, Vue, Prop } from "vue-property-decorator"
import { Table } from 'element-ui'

@Component({
    props: {
        data: {
            type: Array,
            required: true
        },
        selection: {
            type: Boolean,
        },
        column: {
            type: Array,
            required: true
        },
        height: {
            type: String
        },
        page: {
            required: true,
            type: [Object, Boolean],
            default: function() {
                return {
                    PageIndex: 20,
                    PageTotal: 0,
                    PageSize: 1
                }
            }
        },
        rowStyle: {
            type: [Function, Object],
            default: function() {
                return {}
            }
        },
        cellStyle: {
            type: [Function, Object],
            default: function() {
                return {}
            }
        },
        headerStyle: {
            type: [Function, Object],
            default: function() {
                return {
                    backgroundColor: "rgb(221, 221, 221)",
                    color: "black"
                }
            }
        },
        index: {
            type: Boolean,
            default: false
        },
        check: {
            type: Boolean,
            default: false
        },
        loading: {
            type: Boolean,
            default: false
        },
        rowClick: {
            type: Function,
            default: function(){}
        },
    },
    components: {
    }
})
export default class TablePage extends Vue {


    public handleCurrentChange(val: number) {
        this.$emit("page", val);
        console.log(val)
    }

    public select(selection: object[], row:object) {
        this.$emit("select", selection, row);
    }

    public clear(){
        (this.$refs["vtable"] as Table).clearSelection();
    }

    public toggle(){
        (this.$refs["vtable"] as Table).toggleAllSelection();
    }

    public rowChange(selection: object[], row:object){
        this.$emit("rowChange", selection, row);
    }

    public handleSelectionChange(selection: object[]){
        this.$emit("handleSelectionChange", selection);
    }

}
</script>

<style scoped>
    #table_page {
        /* height: 100%; */
    }
    /* #table_page .el-table {
        height: calc(100% - 50px);
    } */
    #table_page .el-table {
        position: relative;
        margin-bottom: 33px;
    }

    #table_page .el-pagination {
        float: right;
        position: fixed;
        bottom: 0;
        z-index: 10;
        right: 0;
        background: #fff;
        text-align: right;
        border-top: 1px solid #eee;
        width: 100%;
    }
</style>


依次解释:
v-loading:对表格添加加载效果。
@row-click:当某一行被点击时会触发该事件。
@select:当用户手动勾选数据行的 Checkbox 时触发的事件
@select-all:当用户手动勾选全选 Checkbox 时触发的事件
@current-change:当表格的当前行发生变化的时候会触发该事件,可以拿到用户当前选中的行数据(无checkbox情况下)。如果要高亮当前行,请打开表格的 highlight-current-row 属性
@selection-change:当选择项发生变化时会触发该事件,选中checkbox和取消时都会触发,可以用来获取用户选中的数据。
:data:数组
stripe:是否为斑马纹 table
highlight-current-row:是否要高亮当前行
:header-cell-style:表头单元格的 style 的回调方法,也可以使用一个固定的 Object 为所有表头单元格设置一样的 Style。
:cell-style:单元格的 style 的回调方法,也可以使用一个固定的 Object 为所有单元格设置一样的 Style。
:row-style:行的 style 的回调方法,也可以使用一个固定的 Object 为所有行设置一样的 Style。
实例:

import vtable from "@/components/common/TablePage.vue";
components: {
    vtable
  }
<vtable
        ref="vtable"
        :page="page"
        @page="pageChange"
        v-loading="loading"
        :data="tableData"
        @select="changeList"
        :selection="true"
        :column="column"
        :headerStyle="{background: '#fff'}"
      >
</vtable>

ts部分:

  //初始化page,Models是我管理interface接口校验的文件,在这里也粘一下
  // 分页interface
export interface Page {
    PageIndex: number
    PageTotal: number
    PageSize: number
}
//分页初始化数据,这里可以与后端约定返回的字段名称
  private page: Models.Page = {
    PageIndex: 1,
    PageTotal: 0,
    PageSize: 20
  };
  //
    public pageChange(e: number) {
    //拿到用户点击的页码
    this.page.PageIndex = e;
    console.log(e);
    //nextPage是封装好的方法,也粘出来
    // 获取下一页页数
	//export const nextPage = (curPage: number, pageSize: number) => {
    //return (curPage - 1) * pageSize
	//}
	//searchForm是el-form的表单数据对象,是做列表筛选功能
    this.searchForm.skipCount = nextPage(e, this.page.PageSize);
    //更新列表
    this.getProductList();
  }
  //Loading效果使用
  private async getProductList() {
    this.loading = true;
    try {
      let res = await GetMixedProducts.request(this.searchForm);
      this.tableData = res.items;
      if (res.items) {
        this.page.PageTotal = res.totalCount!;
      }
    } catch (error) {
    } finally {
      this.loading = false;
    }
  }
  //勾选数据行时触发
    private changeList(selection: Models.Product[], row: Models.Product) {
    this.checkList = [];
    selection.forEach(element => {
      this.checkList.push(element.id);
    });
  }
  //方便理解,把product粘出来
  // 商品列表 node
export interface Product {
    name: string
    productNumber: string
    saleName: string
    displayOrder: number
    isPublished: boolean
    productCoverThumbPictureUrl: string
    isPortal: boolean
    stockQuantity: number
    hasProductPrice: boolean
    usedForMaintenance: boolean
    isComobo: boolean
    id: string
}
//column
private readonly column = [
    {
      label: "商品图片",
      slot: "productCoverThumbPictureUrl",
      width: 140
    },
    {
      label: "产品名称",
      prop: "name"
    },
    {
      label: "商品名称",
      prop: "saleName"
    },
    {
      label: "商品编号",
      prop: "productNumber",
      width: 120
    },
    {
      label: "是否销售商品",
      slot: "isPortal",
      width: 120
    },
    {
      label: "是否服务配件",
      slot: "usedForMaintenance",
      width: 120
    },
    {
      label: "是否套装商品",
      slot: "isComobo",
      width: 120
    },
    {
      label: "显示顺序",
      prop: "displayOrder",
      width: 120
    },
    {
      label: "上架状态",
      slot: "isPublished",
      width: 120
    },
    {
      label: "操作",
      slot: "operate",
      width: 180
    }
  ];

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值