目录
  • 前言
  • 一、为什么要自定义表列模版?
  • 二、实现步骤
    • 1.封装表格组件
    • 2.父组件引用
  • 总结

    前言

    日前vue3项目中用element-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表格自定义列模版的问题,可能还会有更复杂的场景,待遇到时再具体分析。

    声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。