1、vue2 element-ui 表格组件封装

71 阅读2分钟

后管端实际业务页面 大部分都是表格数据页面,但每个页面都要处理 pageSize,pageNum,选择框,等等业务,有没有办法简化这些业务逻辑?

当然有。

结合实际业务逻辑,封装了一个实际的表格代码,除了接口调用相关内容,不需要其他变量,以简化代码量

使用示例 在保持一致性的前提下封装了分页及调用方法,大大减少了业务页面代码复杂度

<template>
    <div>
        <el-button type="primary" @click="Search">获取选择项目</el-button>
        <br>
        <PageTabel @GetData="GetData" ref="table" :select="true">
            <!-- 这样封装的表格,直接使用 element-ui 的原始表格项内容, -->
            <!-- 也支持原有表格的全部属性字段,-->
            <!-- 同时,简化了表格页面开发需要处理的逻辑和变量  -->
            <el-table-column prop="name" label="名称" align="center" />
            <!-- 下方为自己封装的表格单元格组件,以简化基本业务逻辑  -->
            <!-- 下方组件的封装方法在之后的文章中会介绍😂 -->
            <el-table-column-chpher prop="phone" label="电话号" align="center" />
            <el-table-column-chpher prop="idCard" chpherKey="idCardDes" :isChpher="true" label="身份证号" align="center" />
            <el-table-column-tooltip prop="code" width="200" label="tooltip" align="center" />
            <el-table-column-format formatStr="${startTime} 至 ${endTime}" label="拼接" align="center" />
            <el-table-column-dict prop="city" label="字典" code="city" showkey="label" valuekey="value" align="center" />
            <el-table-column-default prop="city" defaultStr="-" label="默认值" align="center" />
        </PageTabel>
    </div>

</template>
<script>
import PageTabel from '../table/index.vue'
export default {
    components: { PageTabel },
    methods: {
        Search() {
            const SelectData = this.$refs.table.GetSelects();
            //                  用上面的方法,获得表格选中的值
            console.log(SelectData)
        },
        GetData(params, callback, errorCallback) {
            // 页面初始化时,会自动调用该方法,来获取数据
            // params返回 pageNum  和 pageSize
            console.log(params);

            setTimeout(() => {
                // 表格数据
                const list = [
                    { name: 'name1', city: "01", startTime: "2025-01-17", endTime: "2025-02-15", code: '{"Code" : "AAABBBCCCDDDEEEFFF"}', phone: '13000000000', idCard: '001***********0001', idCardDes: btoa('001001199001010001') },
                    { name: 'name2', city: "02", startTime: "2025-01-17", endTime: "2025-02-15", code: '一堆文字一堆文字一堆文字一堆文字一堆文字一堆文字一堆文字', phone: '13000000000', idCard: '001***********0001', idCardDes: btoa('001001199001010001') },
                    { name: 'name3', city: "", startTime: "2025-01-17", endTime: "2025-02-15", code: '', phone: '13000000000', idCard: '001***********0001', idCardDes: btoa('001001199001010001') },
                    { name: 'name4', startTime: "2025-01-17", endTime: "2025-02-15", code: '', phone: '13000000000', idCard: '001***********0001', idCardDes: btoa('001001199001010001') },
                ];
                // 表格数据总数
                const total = 100;
                // 使用callback 方法,向表格内部传递数据
                if (params.pageNum == 3) {
                    // 假设了请求第三页请求失败
                    errorCallback();
                } else {
                    callback(list, total);
                }
            }, 1000)
        }
    },
};
</script>

源码展示

相关子组件

<template>
    <div>
        <el-table :data="tableData" ref="table" @selection-change="SetSelects" stripe style="width:100%"
            :row-key="rowKey" :header-cell-style="{ background: '#ECF3FF' }" v-bind="$attrs">
            <!-- 将选择器 封装在表格组件中,减少外部 方法/参数 的创建 -->
            <el-table-column type="selection" width="35" v-if="select"></el-table-column>
            <slot></slot>
        </el-table>
        <div class="page">
            <!-- 将分页组件添加在表格组件中,将逻辑在表格内部处理 -->
            <el-pagination @current-change="GetList" @size-change="ChangeSize" :current-page.sync="pageNum"
                :page-size="pageSize" layout="total,prev,pager,next,jumper,sizes" :total="Number(total || 0)" />
        </div>
    </div>
</template>

<script>
export default {
    props: {
        rowKey: { default: 'id' }, // 用于标记表格唯一key值
        select: { default: false }, // 显示多选框
    },
    data() {
        return {
            loading: false,
            pageNum: 1, // 从表格第一也开始
            pageSize: 10, // 每页数据条数
            total: 0, // 数据总数
            SelectCache: [], // 多选框数据缓存对象
            tableData: [], // 表格数据
            OldPageNum: 1,
            OldPageSize: 10,
        };
    },
    mounted() {
        // 页面加载结束后,初始化数据
        this.GetList();
    },
    methods: {
        // 缓存每次表格单选框选择结果
        SetSelects(val) {
            this.SelectCache = val;
        },
        // 清空选择结果
        ClearSelects() {
            this.SelectCache = [];
            this.$refs.table.clearSelection && this.$refs.table.clearSelection();
        },
        GetSelects() {
            return this.SelectCache;
        },
        ChangeSize(value) {
            // 当表格正在获取数据时,阻止点击事件,方式重复调用,混淆返回值数据
            // (部分需求中,接口返回的每一页数据时间并不一致)
            this.pageSize = value;
            this.GetList();
        },
        // 为表格外部留下重置方法
        ReSet() {
            this.pageSize = 10;
            this.pageNum = 1;
            this.ClearSelects();
            this.GetList();
        },
        // 获取数据的主要参数
        GetList() {
            // 主要的参数获取方法,通过callback 请求表格数据 和 总数
            this.$emit('GetData', {
                pageNum: this.pageNum,
                pageSize: this.pageSize,
            }, (data, total) => {
                this.ClearSelects();
                this.tableData = data || [];
                this.total = total;
            }, () => {
                // 当表格接口出现错误时,清空表格数据
                // 一般情况下是用不到的
                this.tableData = [];
            })
        }
    },
};
</script>

<style lang="less" scoped>
::v-deep(.el-table-column--selection) {
    .cell {
        padding-left: 10px;
        padding-right: 10px;
    }
}
</style>