Skip to content

Commit cb40b0c

Browse files
committed
feat: enhance table rendering with custom slot support and improved cell rendering logic
1 parent 80a24e1 commit cb40b0c

File tree

2 files changed

+26
-15
lines changed

2 files changed

+26
-15
lines changed

frontend/src/components/Table/index.vue

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script lang="ts" setup>
2-
import { ref, computed } from 'vue'
2+
import { ref, computed, isVNode, h } from 'vue'
33
44
import vMenu from '@/directives/menu'
55
import useI18n from '@/lang'
@@ -14,7 +14,7 @@ export type Column = {
1414
hidden?: boolean
1515
minWidth?: string
1616
sort?: (a: Record<string, any>, b: Record<string, any>) => number
17-
customRender?: (v: { value: any; record: Record<string, any> }) => string
17+
customRender?: (v: { value: any; record: Record<string, any> }) => any
1818
}
1919
2020
interface Props {
@@ -60,6 +60,15 @@ const tableData = computed(() => {
6060
const tableColumns = computed(() => {
6161
return props.columns.filter((column) => !column.hidden)
6262
})
63+
64+
const renderCell = (column: Column, record: Recordable) => {
65+
const value = getValue(record, column.key)
66+
let result = column.customRender?.({ value, record }) ?? value ?? '-'
67+
if (!isVNode(result)) {
68+
result = h('div', result)
69+
}
70+
return result
71+
}
6372
</script>
6473

6574
<template>
@@ -88,21 +97,20 @@ const tableColumns = computed(() => {
8897
</thead>
8998
<tbody>
9099
<tr
91-
v-for="data in tableData"
92-
v-menu="menu.map((v) => ({ ...v, handler: () => v.handler?.(data) }))"
93-
:key="data.id"
100+
v-for="record in tableData"
101+
v-menu="menu.map((v) => ({ ...v, handler: () => v.handler?.(record) }))"
102+
:key="record.id"
94103
>
95104
<td
96105
v-for="column in tableColumns"
97106
:key="column.key"
98107
:style="{ textAlign: column.align || 'left' }"
99108
class="select-text"
100-
v-html="
101-
(column.customRender
102-
? column.customRender({ value: getValue(data, column.key), record: data })
103-
: getValue(data, column.key)) ?? '-'
104-
"
105-
></td>
109+
>
110+
<slot :name="column.key" :="{ column, record }">
111+
<component :is="renderCell(column, record)" />
112+
</slot>
113+
</td>
106114
</tr>
107115
</tbody>
108116
</table>

frontend/src/utils/others.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,13 @@ export const generateSecureKey = (bits = 256) => {
6868
.join('')
6969
}
7070

71-
export const getValue = (obj: Record<string, any>, expr: string) => {
72-
return expr.split('.').reduce((value, key) => {
73-
return value[key]
74-
}, obj)
71+
export const getValue = <T = unknown>(obj: unknown, expr: string): T | undefined => {
72+
return expr.split('.').reduce<unknown>((value, key) => {
73+
if (value && typeof value === 'object') {
74+
return (value as Record<string, unknown>)[key]
75+
}
76+
return undefined
77+
}, obj) as T
7578
}
7679

7780
export const asyncPool = async <T>(

0 commit comments

Comments
 (0)