为什么要二次封装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?: string
field: string
title?: string
isFixed?: boolean
width?: number
minWidth?: number
align?: 'left' | 'center' | 'right'
}
interface ElTableColumnPropsTypes {
fixed?: boolean
prop?: string
label?: string
width?: number
minWidth?: number
align?: 'left' | 'center' | 'right'
}
interface ComputedTableConfigItemTypes {
field: string
columnDynamicSlotName: string /* 对外暴露的插槽名称*/
dataFormat: FormatData
tableProps: 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.formatData
let _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>
下面效果图
如果有帮助到你的话,点个赞吧!