为什么要二次封装element-plus的Table 表格组件,言简意赅:以后难免会在表格里面加一些统一的逻辑,可以在表格里面书写重复的方法或样式
封装后的使用方式
props
参数 | 类型 | 可选值 | 默认值 | 说明 |
---|---|---|---|---|
tableData | Array | — | — | 表格数据 |
tableConfig | Array | — | — | 表格配置数组,具体格式如下 |
element-plus Table API 的所有参数传入一样有效
tableConfig 数据格式如下
[{title: "标题",field: "fund_name",//__index和__checkbox 保留field 用于序号和选择框align: "left",width: 200,needTitle: true,setColor: true,format: 1,cellClass: "", //String||(rowData)=>{return String}headerClass: "", //String||(rowData)=>{return String}},
]
封装逻辑
- 首先我们需要一个表格的根组件去引用element-plus,然后根据数据循环
<template><el-table :data="props.tableData" fit size="small" :border="true"><el-table-column v-for="item in computedTableConfig" :key="item.field" v-bind="item.tableProps"><template #default="scope"><slot :name="item.columnDynamicSlotName" :index="scope.$index" :data="scope.row[item.field]":rowData="scope.row" :config="scope.column"><DataItem :val="scope.row[item.field]" :formatData="item.dataFormat"></DataItem></slot></template></el-table-column></el-table>
</template><script lang="ts" setup>
import DataItem from './common/data-item.tsx'
import { FormatData } from './common/data-item.tsx'export interface TableConfigItem extends FormatData {show_name?: stringfield: stringtitle?: stringisFixed?: booleanwidth?: numberminWidth?: numberalign?: 'left' | 'center' | 'right'
}interface ElTableColumnPropsTypes {fixed?: booleanprop?: stringlabel?: stringwidth?: numberminWidth?: numberalign?: 'left' | 'center' | 'right'
}interface ComputedTableConfigItemTypes {field: stringcolumnDynamicSlotName: string /* 对外暴露的插槽名称*/dataFormat: FormatDatatableProps: ElTableColumnPropsTypes
}
const props = defineProps<{tableConfig: TableConfigItem[]tableData: any[]
}>()const computedTableConfig = computed<ComputedTableConfigItemTypes[]>(() => {return props.tableConfig.map((item) => {const _item: ComputedTableConfigItemTypes = {field: item.field,columnDynamicSlotName: 'column_' + item.field,dataFormat: {},tableProps: {}}for (const key in item) {if (key == 'field') {_item.tableProps.prop = item[key]}if (key == 'isFixed') {_item.tableProps.fixed = item[key]}if (key == 'title') {_item.tableProps.label = item[key]}if (['align', 'width', 'minWidth'].includes(key)) {_item.tableProps[key] = item[key]}if (['setColor', 'needTitle', 'format', 'suffix', 'prefix'].includes(key)) {_item.dataFormat[key] = item[key]}}return _item})
})
</script>
- 然后封装处理每一个单元格DataItem的组件(此处我用的是TSX组件)
import { defineComponent } from 'vue'
export interface FormatData extends FormatDataType {setColor?: boolean /* 设置颜色 */needTitle?: boolean /* 是否需要标题 */
}export default defineComponent({name: 'data-item',props: {formatData: {// 表格数据default: () => {},type: Object},val: {required: true}},render() {let { setColor = false, needTitle = false } = this.formatDatalet _color = {}if (setColor) {let _num = parseFloat(res)_num = isNaN(_num) ? 0 : _num_color = _num ? (_num > 0 ? {color:'red'} : {color:'#999999'}) : ''} // 条件判断可以加return (<div style={_color} title={needTitle ? res : ''}>{res}</div>)}
})
- 然后测试组件的实现
<template><div><h2 style="color: red;" :style="{ color: red }">表格1</h2><Htable :tableConfig="tableConfig" :tableData="tableData"></Htable></div>
</template><script setup lang='ts'>
import { ref } from 'vue'
import Htable from "./Htable/index.vue";const value1 = ref(0)
const tableConfig = [{title: "标题",field: "tit",align: "left",width: 200,needTitle: true,},{title: "姓名",field: "name",align: "left",width: 200,needTitle: true,},{title: "身高",field: "height",align: "left",needTitle: true,setColor: true,format: 1,},
]
const tableData = [{tit: '撒旦发生',name: '撒打发',height: 12},{tit: '撒旦发qw生',name: '撒打发',height: 123},{tit: '撒旦发qwe生',name: '撒打发',height: 123},{tit: '撒旦发qw生',name: '撒打发',height: 31}
]
</script><style lang='less' scoped></style>
下面效果图
如果有帮助到你的话,点个赞吧!