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
    }
  ];

在Vue2中,对于element-ui组件的二次封装,可以按照以下步骤进行: 1. 需求分析:明确需要封装element-ui组件,以及需要添加的功能和配置项。 2. 创建父组件:编写父组件的template和script代码,其中template中调用封装组件,script中定义需要传递给封装组件的props属性。 3. 创建封装组件:编写封装组件的template和script代码。在template中使用element-ui组件,并根据需要进行样式和布局的调整。在script中定义props属性,接收父组件传递的值,并监听element-ui组件的事件,触发update事件给父组件。 4. 通过临时变量传递值:由于父组件传递给封装组件的props不能直接作为封装组件的v-model属性传递给element-ui组件,所以需要在封装组件中定义一个临时变量来存储值,并将该变量与element-ui组件进行绑定。 5. 完成打通:在封装组件中监听中间件,接收到element-ui组件的update事件后,再将该事件传递给父组件。 总结来说,Vue2中对于element-ui组件的二次封装,需要创建父组件和封装组件,通过props属性传递值,并在封装组件中监听element-ui组件的事件并触发update事件给父组件。同时,需要使用临时变量来传递值给element-ui组件。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [Vue3+ts+element-plus 组件的二次封装-- 页脚分页el-pagination的二次封装](https://blog.youkuaiyun.com/cs492934056/article/details/128096257)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v92^chatsearchT3_1"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值