我们平常都会将element-table封装一次,方便复用,减少不必要的代码。参考ant-design的table组件用法,试着封装了一下。
第一种直接使用SFC的vue文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40<template>
<el-table style="width: 100%">
<template v-for="item in tableHeader" :key="item.dataIndex">
<el-table-column show-overflow-tooltip v-if="item.slotName || item.render" :prop="item.dataIndex" :label="item.title"
:sortable="item.sortable" :align="item.align || null" :width="item.width">
<template #default="scope">
<div v-if="item.render" >
{{ item.render({
data: scope.row
}) }}
</div>
<slot v-else :name="item.slotName" :data="scope.row"></slot>
</template>
</el-table-column>
<el-table-column show-overflow-tooltip v-else :prop="item.dataIndex" :label="item.title" :sortable="item.sortable"
:align="item.align || null" :width="item.width" />
</template>
<slot />
</el-table>
</template>
<script lang="ts" setup>
import { VNodeChild } from 'vue';
interface tableHeaderItem {
dataIndex: string
title: string
slotName?: string
align?: string
width?: string
sortable?: boolean
render?: VNodeChild
}
const props = defineProps<{
tableData: any,
tableHeader: tableHeaderItem[]
}>()
</script>slotName可以自定义当前列的表格内容以及样式render可以自定义当前列的表格内容
用法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58<template>
<div class="table">
<NewElTable :data="tableData" :table-header="tableHeader" size="small">
<template #name="{ data }">
<div>{{ data.name }}</div>
</template>
</NewElTable>
</div>
</template>
<script setup>
import NewElTable from "@/components/new-el-table/index.vue"
const tableHeader = [
{
dataIndex: 'date',
title: '日期',
},
{
dataIndex: 'name',
title: '名字',
slotName: 'name',
},
{
dataIndex: 'address',
title: '地址',
render({ data }) {
//在这里可以做一些map解构或者计算
return data.address
}
}
]
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
]
</script>
<style scoped>
.table {
width: 500px;
}
</style>使用
t/jsx来封装1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
```jsx
import { defineComponent } from "vue";
import { ElTable, ElTableColumn } from "element-plus";
export default defineComponent({
props: {
tableHeader: {
type: Array,
default: []
}
},
setup(props) {
const { tableHeader } = props
return () =>
(
<ElTable style="width: 100%">
{
tableHeader.map(item => {
if (item.render) {
return <>
<ElTableColumn show-overflow-tooltip prop={item.dataIndex} label={item.title} sortable={item.sortable} align={item.align || null} width={item.width}
v-slots={{
default: (scope) => <>
{
item.render({
data: scope.row
})
}
</>
}}>
</ElTableColumn>
</>
} else if (item.slotName) {
return <>
<ElTableColumn show-overflow-tooltip prop={item.dataIndex} label={item.title}
sortable={item.sortable} align={item.align || null} width={item.width} v-slots={{
default: (scope) => <>
{this.$slots.default(scope.row)}
</>
}}>
</ElTableColumn>
</>
} else {
return <ElTableColumn show-overflow-tooltip prop={item.dataIndex} label={item.title}
sortable={item.sortable} align={item.align || null} width={item.width}>
</ElTableColumn>
}
})
}
</ElTable>
)
}
})这种方式和上面的区别主要在于
render,可以使用h函数,也可以使用t/jsx抛出的方法,如下:1
2
3
4
5
6
7
8//demo.jsx
export default function demo({data}) {
return (
<>
<div>{data.address}</div>
</>
)
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67//app.vue
<template>
<div class="table">
<NewElTable :data="tableData" :table-header="tableHeader" size="small">
<template #name="{ data }">
<div>{{ data.name }}</div>
</template>
</NewElTable>
</div>
</template>
<script setup>
import NewElTable from "@/components/new-el-table/index.vue"
const tableHeader = [
{
dataIndex: 'date',
title: '日期',
},
{
dataIndex: 'name',
title: '名字',
slotName: 'name',
render({ data }) {
return h('div', {
innerHTML: data.name,
style: {
color: 'red'
}
})
}
},
{
dataIndex: 'address',
title: '地址',
render: demo
}
]
const tableData = [
{
date: '2016-05-03',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-02',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-04',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
{
date: '2016-05-01',
name: 'Tom',
address: 'No. 189, Grove St, Los Angeles',
},
]
</script>
<style scoped>
.table {
width: 500px;
}
</style>
最后有个疑惑,就是在第一种里面,如何修改可以让render支持h函数和t/jsx