|
1 | 1 | <script lang="ts"> |
2 | | -import type { ColumnDef, RowData, Table } from '@tanstack/vue-table' |
| 2 | +import type { ColumnDef, RowData, Table, TableOptionsWithReactiveData } from '@tanstack/vue-table' |
3 | 3 | import type { CellSlotProps, FooterSlotProps, HeaderSlotProps } from '../shared/types' |
4 | 4 |
|
| 5 | +export type TableOptions = Omit<TableOptionsWithReactiveData<any>, 'columns' | 'data' | 'getCoreRowModel'> |
| 6 | +
|
5 | 7 | export interface TSTableProps<TData extends RowData & object> { |
6 | 8 | columns: ColumnDef<TData, any>[] |
7 | 9 | data: TData[] |
8 | | - tableOptions?: Record<string, any> |
| 10 | + tableOptions?: TableOptions |
9 | 11 | } |
10 | 12 | </script> |
11 | 13 |
|
12 | 14 | <script setup lang="ts" generic="TData extends RowData & object"> |
13 | | -import { computed, useSlots } from 'vue' |
14 | | -import { useVueTable, createColumnHelper, type ColumnDef as TStackColumnDef, getCoreRowModel } from '@tanstack/vue-table' |
| 15 | +import { computed, useSlots, watch } from 'vue' |
| 16 | +import { useVueTable, createColumnHelper, getCoreRowModel } from '@tanstack/vue-table' |
15 | 17 | import { processColumns } from '../shared' |
16 | 18 |
|
17 | 19 | const props = defineProps<TSTableProps<TData>>() |
18 | 20 |
|
19 | 21 | const slots = useSlots() |
20 | 22 | const columnHelper = createColumnHelper<TData>() |
21 | 23 |
|
| 24 | +// Use memo pattern for expensive column processing |
22 | 25 | const processedColumns = computed(() => { |
23 | | - const initialTable = useVueTable<TData>({ |
24 | | - columns: props.columns as TStackColumnDef<TData, any>[], |
25 | | - data: props.data, |
26 | | - getCoreRowModel: getCoreRowModel(), |
27 | | - ...props.tableOptions |
28 | | - }) |
29 | | - return processColumns(columnHelper, props.columns, slots, initialTable) |
| 26 | + return processColumns(columnHelper, props.columns, slots) |
30 | 27 | }) |
31 | 28 |
|
32 | | -const tableOptions = { |
| 29 | +// Create initial table options |
| 30 | +const initialTableOptions = { |
33 | 31 | columns: processedColumns.value, |
34 | 32 | data: props.data, |
35 | 33 | getCoreRowModel: getCoreRowModel(), |
36 | 34 | ...props.tableOptions |
37 | 35 | } |
38 | 36 |
|
39 | | -const table = useVueTable<TData>(tableOptions) |
| 37 | +// Initialize table with initial options |
| 38 | +const table = useVueTable<TData>(initialTableOptions) |
| 39 | +
|
| 40 | +// Watch for data changes and update table efficiently |
| 41 | +watch(() => props.data, (newData) => { |
| 42 | + table.setOptions((old) => ({ |
| 43 | + ...old, |
| 44 | + data: newData, |
| 45 | + })) |
| 46 | +}, { flush: 'sync' }) |
| 47 | +
|
| 48 | +// Watch columns separately to avoid unnecessary recalculations |
| 49 | +watch(processedColumns, (newColumns) => { |
| 50 | + table.setOptions((old) => ({ |
| 51 | + ...old, |
| 52 | + columns: newColumns, |
| 53 | + })) |
| 54 | +}, { flush: 'sync' }) |
40 | 55 |
|
41 | 56 | defineSlots<{ |
42 | 57 | default: (props: { |
|
0 commit comments