Browse Source

chore(component): add generic support for useTable

main
刘凯 1 year ago
parent
commit
c95b60fc29
  1. 24
      src/components/Table/src/hooks/useTable.ts
  2. 70
      src/components/Table/src/types/table.ts

24
src/components/Table/src/hooks/useTable.ts

@ -9,25 +9,25 @@ import { getDynamicProps } from '@/utils'
import { isProdMode } from '@/utils/env' import { isProdMode } from '@/utils/env'
import { error } from '@/utils/log' import { error } from '@/utils/log'
type Props = Partial<DynamicProps<BasicTableProps>> type Props<T> = Partial<DynamicProps<BasicTableProps<T>>>
type UseTableMethod = TableActionType & { type UseTableMethod = TableActionType & {
getForm: () => FormActionType getForm: () => FormActionType
} }
export function useTable(tableProps?: Props): [ export function useTable<T>(tableProps?: Props<T>): [
(instance: TableActionType, formInstance: UseTableMethod) => void, (instance: TableActionType<T>, formInstance: UseTableMethod) => void,
TableActionType & { TableActionType<T> & {
getForm: () => FormActionType getForm: () => FormActionType
}, },
] { ] {
const tableRef = ref<Nullable<TableActionType>>(null) const tableRef = ref<Nullable<TableActionType<T>>>(null)
const loadedRef = ref<Nullable<boolean>>(false) const loadedRef = ref<Nullable<boolean>>(false)
const formRef = ref<Nullable<UseTableMethod>>(null) const formRef = ref<Nullable<UseTableMethod>>(null)
let stopWatch: WatchStopHandle let stopWatch: WatchStopHandle
function register(instance: TableActionType, formInstance: UseTableMethod) { function register(instance: TableActionType<T>, formInstance: UseTableMethod) {
isProdMode() isProdMode()
&& onUnmounted(() => { && onUnmounted(() => {
tableRef.value = null tableRef.value = null
@ -56,17 +56,17 @@ export function useTable(tableProps?: Props): [
) )
} }
function getTableInstance(): TableActionType { function getTableInstance(): TableActionType<T> {
const table = unref(tableRef) const table = unref(tableRef)
if (!table) { if (!table) {
error( error(
'The table instance has not been obtained yet, please make sure the table is presented when performing the table operation!', 'The table instance has not been obtained yet, please make sure the table is presented when performing the table operation!',
) )
} }
return table as TableActionType return table as TableActionType<T>
} }
const methods: TableActionType & { const methods: TableActionType<T> & {
getForm: () => FormActionType getForm: () => FormActionType
} = { } = {
reload: async (opt?: FetchParams) => { reload: async (opt?: FetchParams) => {
@ -124,16 +124,16 @@ export function useTable(tableProps?: Props): [
getSize: () => { getSize: () => {
return toRaw(getTableInstance().getSize()) return toRaw(getTableInstance().getSize())
}, },
updateTableData: (index: number, key: string, value: any) => { updateTableData: <K extends keyof T>(index: number, key: K, value: T[K]) => {
return getTableInstance().updateTableData(index, key, value) return getTableInstance().updateTableData(index, key, value)
}, },
deleteTableDataRecord: (rowKey: string | number | string[] | number[]) => { deleteTableDataRecord: (rowKey: string | number | string[] | number[]) => {
return getTableInstance().deleteTableDataRecord(rowKey) return getTableInstance().deleteTableDataRecord(rowKey)
}, },
insertTableDataRecord: (record: Recordable | Recordable[], index?: number) => { insertTableDataRecord: (record: T | T[], index?: number) => {
return getTableInstance().insertTableDataRecord(record, index) return getTableInstance().insertTableDataRecord(record, index)
}, },
updateTableDataRecord: (rowKey: string | number, record: Recordable) => { updateTableDataRecord: (rowKey: string | number, record: T) => {
return getTableInstance().updateTableDataRecord(rowKey, record) return getTableInstance().updateTableDataRecord(rowKey, record)
}, },
findTableDataRecord: (rowKey: string | number) => { findTableDataRecord: (rowKey: string | number) => {

70
src/components/Table/src/types/table.ts

@ -83,10 +83,10 @@ export interface GetColumnsParams {
export type SizeType = 'default' | 'middle' | 'small' | 'large' export type SizeType = 'default' | 'middle' | 'small' | 'large'
export interface TableActionType { export interface TableActionType<T = Recordable> {
reload: (opt?: FetchParams) => Promise<void> reload: (opt?: FetchParams) => Promise<void>
setSelectedRows: (rows: Recordable[]) => void setSelectedRows: (rows: Recordable[]) => void
getSelectRows: <T = Recordable>() => T[] getSelectRows: () => T[]
clearSelectedRowKeys: () => void clearSelectedRowKeys: () => void
expandAll: () => void expandAll: () => void
expandRows: (keys: (string | number)[]) => void expandRows: (keys: (string | number)[]) => void
@ -95,14 +95,14 @@ export interface TableActionType {
getSelectRowKeys: () => Key[] getSelectRowKeys: () => Key[]
deleteSelectRowByKey: (key: string) => void deleteSelectRowByKey: (key: string) => void
setPagination: (info: Partial<PaginationProps>) => void setPagination: (info: Partial<PaginationProps>) => void
setTableData: <T = Recordable>(values: T[]) => void setTableData: (values: T[]) => void
updateTableDataRecord: (rowKey: string | number, record: Recordable) => Recordable | void updateTableDataRecord: (rowKey: string | number, record: T) => T | void
deleteTableDataRecord: (rowKey: string | number | string[] | number[]) => void deleteTableDataRecord: (rowKey: string | number | string[] | number[]) => void
insertTableDataRecord: (record: Recordable | Recordable[], index?: number) => Recordable[] | void insertTableDataRecord: (record: T | T[], index?: number) => T[] | void
findTableDataRecord: (rowKey: string | number) => Recordable | void findTableDataRecord: (rowKey: string | number) => T | void
getColumns: (opt?: GetColumnsParams) => BasicColumn[] getColumns: (opt?: GetColumnsParams) => BasicColumn[]
setColumns: (columns: BasicColumn[] | string[]) => void setColumns: (columns: BasicColumn[] | string[]) => void
getDataSource: <T = Recordable>() => T[] getDataSource: () => T[]
getRawDataSource: <T = Recordable>() => T getRawDataSource: <T = Recordable>() => T
setLoading: (loading: boolean) => void setLoading: (loading: boolean) => void
setProps: (props: Partial<BasicTableProps>) => void setProps: (props: Partial<BasicTableProps>) => void
@ -110,10 +110,10 @@ export interface TableActionType {
setSelectedRowKeys: (rowKeys: Key[]) => void setSelectedRowKeys: (rowKeys: Key[]) => void
getPaginationRef: () => PaginationProps | boolean getPaginationRef: () => PaginationProps | boolean
getSize: () => SizeType getSize: () => SizeType
getRowSelection: () => TableRowSelection<Recordable> getRowSelection: () => TableRowSelection<T>
getCacheColumns: () => BasicColumn[] getCacheColumns: () => BasicColumn[]
emit?: EmitType emit?: EmitType
updateTableData: (index: number, key: string, value: any) => Recordable updateTableData: <K extends keyof T>(index: number, key: K, value: T[K]) => Promise<T>
setShowPagination: (show: boolean) => Promise<void> setShowPagination: (show: boolean) => Promise<void>
getShowPagination: () => boolean getShowPagination: () => boolean
setCacheColumnsByField?: (dataIndex: string | undefined, value: BasicColumn) => void setCacheColumnsByField?: (dataIndex: string | undefined, value: BasicColumn) => void
@ -141,7 +141,7 @@ export interface TableSetting {
fullScreen?: boolean fullScreen?: boolean
} }
export interface BasicTableProps<T = any> { export interface BasicTableProps<T = Recordable<any>> {
// 点击行选中 // 点击行选中
clickToRowSelect?: boolean clickToRowSelect?: boolean
isTreeTable?: boolean isTreeTable?: boolean
@ -166,8 +166,10 @@ export interface BasicTableProps<T = any> {
showSummary?: boolean showSummary?: boolean
// 是否可拖拽列 // 是否可拖拽列
canColDrag?: boolean canColDrag?: boolean
// 接口请求对象 /**
api?: (...arg: any) => Promise<any> * , `src/settings/componentSetting.ts > table > fetchSetting`
*/
api?: (...arg: any) => Promise<T[] | { list: T[], pageNo?: number, pageSize?: number, total?: number }>
// 请求之前处理参数 // 请求之前处理参数
beforeFetch?: Fn beforeFetch?: Fn
// 自定义处理接口返回参数 // 自定义处理接口返回参数
@ -189,7 +191,7 @@ export interface BasicTableProps<T = any> {
// 表单配置 // 表单配置
formConfig?: Partial<FormProps> formConfig?: Partial<FormProps>
// 列配置 // 列配置
columns: BasicColumn[] columns: BasicColumn<T>[]
// 是否显示序号列 // 是否显示序号列
showIndexColumn?: boolean showIndexColumn?: boolean
// 序号列配置 // 序号列配置
@ -207,9 +209,9 @@ export interface BasicTableProps<T = any> {
// 在分页改变的时候清空选项 // 在分页改变的时候清空选项
clearSelectOnPageChange?: boolean clearSelectOnPageChange?: boolean
// //
rowKey?: string | ((record: Recordable) => string) rowKey?: keyof T | ((record: T) => keyof T)
// 数据 // 数据
dataSource?: Recordable[] dataSource?: T[]
// 标题右侧提示 // 标题右侧提示
titleHelpMessage?: string | string[] titleHelpMessage?: string | string[]
// 表格滚动最大高度 // 表格滚动最大高度
@ -412,13 +414,13 @@ export interface BasicTableProps<T = any> {
onColumnsChange?: (data: ColumnChangeParam[]) => void onColumnsChange?: (data: ColumnChangeParam[]) => void
} }
export type CellFormat = export type CellFormat<T = Recordable> =
| string | string
| ((text: string, record: Recordable, index: number) => string | number) | ((text: string, record: T, index: number) => string | number)
| Map<string | number, any> | Map<string | number, any>
export interface DefaultBasicColumn extends Omit<ColumnProps<Recordable>, 'filters'> { export interface DefaultBasicColumn<T> extends Omit<ColumnProps<T>, 'filters'> {
children?: BasicColumn[] children?: BasicColumn<T>[]
filters?: { filters?: {
text: string text: string
value: string value: string
@ -434,19 +436,19 @@ export interface DefaultBasicColumn extends Omit<ColumnProps<Recordable>, 'filte
slots?: Recordable slots?: Recordable
// 自定义header渲染 // 自定义header渲染
customHeaderRender?: (column: BasicColumn) => string | VNodeChild | JSX.Element customHeaderRender?: (column: BasicColumn<T>) => string | VNodeChild | JSX.Element
// Whether to hide the column by default, it can be displayed in the column configuration // Whether to hide the column by default, it can be displayed in the column configuration
defaultHidden?: boolean defaultHidden?: boolean
// Help text for table column header // Help text for table column header
helpMessage?: string | string[] | VNodeChild | JSX.Element helpMessage?: string | string[] | VNodeChild | JSX.Element
format?: CellFormat format?: CellFormat<T>
// 权限编码控制是否显示 // 权限编码控制是否显示
auth?: RoleEnum | RoleEnum[] | string | string[] auth?: RoleEnum | RoleEnum[] | string | string[]
// 业务控制是否显示 // 业务控制是否显示
ifShow?: boolean | ((column: BasicColumn) => boolean) ifShow?: boolean | ((column: BasicColumn<T>) => boolean)
/** /**
* default is not editable * default is not editable
@ -454,36 +456,36 @@ export interface DefaultBasicColumn extends Omit<ColumnProps<Recordable>, 'filte
edit?: false edit?: false
} }
export interface EditableBasicColumn<T extends ComponentType = any> extends Omit<DefaultBasicColumn, 'edit'> { export interface EditableBasicColumn<T, C extends ComponentType = any> extends Omit<DefaultBasicColumn<T>, 'edit'> {
edit: true edit: true
editRow?: boolean editRow?: boolean
editable?: boolean editable?: boolean
editComponent: T editComponent: C
editComponentProps?: editComponentProps?:
| ((opt: { | ((opt: {
text: string | number | boolean | Recordable text: string | number | boolean | Recordable
record: Recordable record: T
column: EditableBasicColumn column: EditableBasicColumn<T>
index: number index: number
}) => ComponentProps[T]) }) => ComponentProps[C])
| ComponentProps[T] | ComponentProps[C]
editRule?: boolean | ((text: string, record: Recordable) => Promise<string>) editRule?: boolean | ((text: string, record: T) => Promise<string>)
editValueMap?: (value: any) => string editValueMap?: (value: any) => string
onEditRow?: () => void onEditRow?: () => void
// 自定义修改后显示的内容 // 自定义修改后显示的内容
editRender?: (opt: { editRender?: (opt: {
text: string | number | boolean | Recordable text: string | number | boolean | Recordable
record: Recordable record: T
column: EditableBasicColumn column: EditableBasicColumn<T>
index: number index: number
}) => VNodeChild | JSX.Element }) => VNodeChild | JSX.Element
// 动态 Disabled // 动态 Disabled
editDynamicDisabled?: boolean | ((record: Recordable) => boolean) editDynamicDisabled?: boolean | ((record: T) => boolean)
} }
type EditableBasicColumns<T extends ComponentType = ComponentType> = T extends any ? EditableBasicColumn<T> : never type EditableBasicColumns<T, C extends ComponentType = ComponentType> = C extends any ? EditableBasicColumn<T, C> : never
export type BasicColumn = DefaultBasicColumn | EditableBasicColumns export type BasicColumn<T = Recordable> = DefaultBasicColumn<T> | EditableBasicColumns<T>
export interface ColumnChangeParam { export interface ColumnChangeParam {
dataIndex: string dataIndex: string