vue基于ElementUI二次封装Table+分页

话不多说直接上代码,首先我们先封装el-table组件,里面的item都是日常用到的基本el-table-column,对于复杂的el-table-column 我们可以定义插槽进行自定义扩展

// SimpleTable
<!--
 * @FileDescription: 基于elementUI的表格二次封装
 * @Author: wz
 * @Date: 2023-02-27 15:17
 * @remakrs: 
    data:表格数据源
    loading:表格加载状态
    columns:表格表头配置项
    pagination: 分页配置项
 -->
<template>
    <div class="simple_table">
        <el-table 
        :data="data"  
        border
        style="width: 100%" 
        v-loading="loading" 
        element-loading-text="数据加载中" 
        element-loading-spinner="el-icon-loading" 
        element-loading-background="rgba(6, 91, 91,0.9)"
        @selection-change="handleTableCurrentChange"
        :row-style="{ height: '55px' }"
        :cell-style="{ padding: '0px' }"
        :header-cell-style="headStyle"
        :cell-class-name="rowClass"
        >
            <template v-for="(item,index) in columns">
                <!-- 选择多行数据时使用 Checkbox。 -->
                <el-table-column  v-if="item.type === 'selection'" :align="'center'"  :fixed="item.fixed" :key="item.type+index" type="selection" ></el-table-column>
                <!-- 序号 -->
                <el-table-column  v-if="item.type === 'index'" :align="'center'"  :fixed="item.fixed" :label="item.label || '序号'" :width="item.width || 60"   :key="item.type+index" type="index"></el-table-column>
                <!-- 常规文本内容 -->
                <el-table-column v-if="item.type ==='text'" :align="'center'"  :width="item.width || ''" :formatter="item.formatter || null" :fixed="item.fixed" show-overflow-tooltip :label="item.label"  :key="item.type+index" :prop="item.key"></el-table-column>
                <!-- 日期内容 -->
                <el-table-column v-if="item.type ==='date'" :align="'center'" :fixed="item.fixed" :width="item.width || 150"   show-overflow-tooltip :label="item.label"  :key="item.type+index">
                    <template slot-scope="scope">
                        <div>{
    
    { scope.row[item.key] | formateDate }}</div>
                    </template>
                </el-table-column>
                <!-- 自定义内容 -->
                <slot v-if="item.type ==='slot'" show-overflow-tooltip :name="item.name"></slot>
            </template>
        </el-table>
        <!-- 分页 -->
        <div class="pagination_box">
            <el-pagination 
                v-if="isPaginationShow && pagination.total"
                style="margin-top: 10px"
                background
                :page-size="pagination.size"
                :current-page.sync="pagination.current"
                :total="pagination.total"
                layout="total, sizes,prev, pager, next,jumper"
                @size-change="handleSizeChange"
                @current-change="handleCurrentChange"
            >
            </el-pagination>
        </div>
    </div>
</template>

<script>
// 根据自己的业务进行日期转换
import { formatDateTime } from '@/utils/date'
export default {
    name:'simpleTable',
    props:{
        data:{
            type:Array,
            default:()=> []
        },
        columns: {
            type: Array,
            default: () => [],
        },
        stripe:{
            type:Boolean,
            default:true
        },
        border:{
            type:Boolean,
            default:true
        },
        loading:{
            type:Boolean,
            default:false
        },
        isPaginationShow: {
            type: Boolean,
            default: true,
        },
        rowClass:{
            type: Function,
            default: ()=>'',
        },
        pagination: {
            type: Object,
            default: () => ({
                current: 1,
                size: 10,
                total: 0,
            }),
        },

    },
    data() {
        return {
            
        }
    },
    filters: {
        formateDate(val) {
            return formatDateTime(val)
        }
    },
    methods:{
        headStyle(){
            return "text-align:center"
        },
        // 切换页码
        handleCurrentChange(val) {
            this.$emit('handleCurrentChange',val);
        },
        // 切换每页条数
        handleSizeChange(value) {
            // current-page和 page-size都支持 .sync修饰符,用了.sync修饰符,就不需要手动给 this.pagination赋值了
            this.pagination.size = value;
            this.$emit('getData');
        },
        // 切换选择
        // handleSelectionChange(val) {
        //     this.$emit('changeSelection', val);
        // },
        // 单选
        handleTableCurrentChange(currentRow) {
            this.$emit('changeCurrent', currentRow);
        },
    }
}
</script>

<style lang="scss" scoped>

</style>

具体如何使用呢,我这里也把几个场景的代码贴出来,

首先先引入并注册组件,这里贴上template中使用的代码

      <SimpleTable :data="tableData" :columns="columns" :rowClass="rowClass" :pagination="pagination" @handleCurrentChange="handleCurrentChange" @changeCurrent="changeCurrent">
                <el-table-column slot="action" :align="'center'" :label="'操作'" width="150">
                    <template slot-scope="scope">
                        <el-button type="text" size="small" @click="operationStation(6,scope.row)" class="qgreen" >查看
                        </el-button>
                        <el-divider
                        direction="vertical"
                        ></el-divider>
                        <!-- <el-button type="text" size="small" @click="editRecord(scope.row)" class="qgreen">
                            修改
                        </el-button>
                        <el-divider  direction="vertical"  ></el-divider> -->
                        <el-button type="text" size="small" @click="batchDel(1,scope.row.cardNo)" class="color-danger" >
                            删除
                        </el-button>
                    </template>
                </el-table-column>
            </SimpleTable>

这是date里的数据,type:'selection' 是表单多选checkbox,formatter是定义每列数据的格式化,

slot则是定义的具名插槽,这里的name:"action"要和上面的slot="action"保持一致

tableData:[],
columns:[
    { type:'selection'},
    { type:'index'},
    { type:'text',key:'cardNo',label:'卡号'},
    { type:'text',key:'batchId',label:'批次号'},
    { type:'text',key:'firstSubjectName',label:'合作机构名称'},
    { type:'text',key:'cardStatus',label:'会员卡状态',formatter:this.cellFormatter},
    { type:'text',key:'cardType',label:'会员卡类型',formatter:this.cellFormatter},
    { type:'text',key:'durationDays',label:'可用时间(天)'},
    { type:'text',key:'qrCodeGenerated',label:'二维码生成',formatter:this.cellFormatter},
    { type:'date',key:'lastActivityTime',label:'最后激活时间'},
    { type:'slot',name:"action"}
]
pagination: {
    current: 1,
    size: 10,
    total: 1,
},

这里是methods代码

// 根据列的值动态显示样式 仅为示例,具体根据自身业务更改
rowClass(col){
    if(col.column.property === 'qrCodeGenerated'){
        return col.row.qrCodeGenerated === 'NO' ? 'color-danger' : 'color-success'
    }
},
// 每列对应需要格式化的内容
cellFormatter(row, column, cellValue, index){
    let showLabel =''
    if(column.property === 'cardStatus'){
        this.cardStatus.forEach(x=>{
            if(x.value === cellValue){
               showLabel= x.label 
            }
        })
    }
    ……
    if(column.property === 'qrCodeGenerated'){
        showLabel= cellValue === 'YES'? '是':'否' 
    }
    return showLabel || '-'
},

至此二次封装的table就可以愉快的使用了,有什么问题给我留言吧...

猜你喜欢

转载自blog.csdn.net/weixin_42301688/article/details/129680491