Bootstrap

前端-vue+elment-ui之表格自定义列模版

表格自定义列模版



前言

日前vue3项目中用elment-ui表格封装一个组件,有自定义表列格式的需求,做完后顺手总结一下


一、为什么要自定义表列模版?

后端返回的数据往往比较原始,比如状态是数值,而我们要给它转成中文并用不同颜色标记,这种场景很常见

二、实现步骤

1.封装表格组件

代码如下(示例):

通过插槽v-slots实现

// data-table/index.tsx

import { ElPagination, ElTable, ElTableColumn } from "element-plus";
import { PropType, defineComponent } from "vue";

const props = {
    tableStyle: {
        type: String as PropType<string>,
        default: 'height: 150px;overflow-y: auto'
    },
    showHeader: {
        type: Boolean as PropType<boolean>,
        default: true
    },
    tableData: {
        type: Array
    },
    columns: {
        type: [Array, Object]
    },
    pagination: {
        type: Object,
        default: () => ({
            total: 0,
            page: 1,
            limit: 20,
            background: true,
            pageSizes: [10, 20, 30, 50],
            pagerCount: document.body.clientWidth < 992 ? 5 : 7,
            layout: '->, total, sizes, prev, pager, next, jumper',
        })
    }
}

export default defineComponent({
    name: 'data-table',
    props,
    setup(props) {
        const defaultBackground = true
        const defaultPageSizes = [10, 20, 30, 50]
        const defaultPagerCount = document.body.clientWidth < 992 ? 5 : 7
        const defaultLayout = '->, total, sizes, prev, pager, next, jumper'
        
        return () => (
            <>
                <div style={ props.tableStyle }>
                    <ElTable v-show={ props.tableData?.length>0 } showHeader={ props.showHeader } v-model:data={ props.tableData } style={{width: '100%'}}>
                        {props.columns?.map((item) => (
                            <ElTableColumn 
                                key={ item.key? item.key:item }
                                prop={ item.prop? item.prop:item }
                                label={ item.label? item.label:item }
                                sortable={ item.sortable }
                                v-slots={{
                                    default: (scope) => item.render? item.render(scope.row):undefined
                                }}
                                />
                        ))}
                    </ElTable>
                    <ElPagination 
                        v-show={ props.pagination.total>0 }
                        small 
                        total={ props.pagination.total }
                        background={ props.pagination.background || defaultBackground }
                        pageSizes={ props.pagination.pageSizes || defaultPageSizes }
                        pagerCount={ props.pagination.pagerCount || defaultPagerCount}
                        layout={ props.pagination.layout || defaultLayout }/>
                </div>
            </>
        )
    }
})

2.父组件引用

代码如下(示例):

在columns中提供render

// parentComponent

export default defineComponent({
    name: 'parent',
    setup() {
        const columns = [
            {key: 'type', prop: 'type', label: 'type', render: (row) => <ElTag>{ row.type }</ElTag>}, 
            {key: 'parseTrue', prop: 'parseTrue', label: 'parseTrue', render: (row) => {
                return row.parseTrue? <ElTag type='success'>语法正确</ElTag> : <ElTag type='danger'>语法错误</ElTag>
            }}, 
            {key: 'explainTrue',prop: 'explainTrue', label: 'explainTrue', render: (row) => {
                return row.explainTrue? <ElTag type='success'>逻辑正确</ElTag> : <ElTag type='danger'>逻辑错误</ElTag>
            }}, 
            {key: 'explainTime', prop: 'explainTime', label: 'explainTime'}, 
            {key: 'sql', prop: 'sql', label: 'sql'}
        ]
        const tableData = ref([])
        const total = ref(0)

        return () => (
            <>
                <DataTable
                    tableStyle='height: 500px;overflow-y: auto'
                    showHeader={ false }
                    columns={ columns }
                    tableData={ tableData.value }
                    pagination={{
                        total: total.value
                    }}
                />
            </>
        )
    }
})

两步就好,不多不少。


总结

通过插槽完美解决了element-ui表格自定义列模版的问题,可能还会有更复杂的场景,待遇到时再具体分析。

;