Files
lingji-work-fe/src/hooks/useTableSelectionWithPagination.ts

99 lines
2.8 KiB
TypeScript
Raw Normal View History

2025-07-15 17:45:16 +08:00
import { ref, computed } from 'vue';
interface UseTableSelectionWithPaginationOptions {
rowKey?: string; // 主键字段名,默认 'id'
pageInfo?: {
page?: number;
page_size?: number;
total?: number;
};
onPageChange?: (page: number) => void;
onPageSizeChange?: (size: number) => void;
onSelectChange?: () => void;
2025-07-15 17:45:16 +08:00
}
const DEFAULT_PAGE_INFO = {
page: 1,
2025-07-15 17:46:09 +08:00
page_size: 20,
2025-07-15 17:45:16 +08:00
total: 0,
};
export function useTableSelectionWithPagination(options: UseTableSelectionWithPaginationOptions = {}) {
const rowKey = options.rowKey || 'id';
const selectedRowKeys = ref<Array<string | number>>([]);
2025-09-05 10:39:01 +08:00
const selectedRows = ref<Array<any>>([]);
2025-07-15 17:45:16 +08:00
const pageInfo = ref(merge({}, DEFAULT_PAGE_INFO, options.pageInfo));
const dataSource = ref<any[]>([]);
// 单行选择
2025-09-05 10:39:01 +08:00
const handleSelect = (record: any, select: boolean) => {
const _targetKey = record[rowKey];
2025-07-15 17:45:16 +08:00
if (select) {
2025-09-05 10:39:01 +08:00
selectedRows.value.push(record);
selectedRowKeys.value.push(_targetKey);
2025-07-15 17:45:16 +08:00
} else {
2025-09-05 10:39:01 +08:00
selectedRows.value = selectedRows.value.filter((v) => v[rowKey] !== _targetKey);
selectedRowKeys.value = selectedRowKeys.value.filter((key) => key !== _targetKey);
2025-07-15 17:45:16 +08:00
}
2025-09-05 10:39:01 +08:00
options.onSelectChange?.();
2025-07-15 17:45:16 +08:00
};
// 全选/取消全选
const handleSelectAll = (checked: boolean) => {
const currentPageRows = dataSource.value;
const currentPageKeys = currentPageRows.map((v) => v[rowKey]);
if (checked) {
selectedRowKeys.value = Array.from(new Set([...selectedRowKeys.value, ...currentPageKeys]));
const allRows = [...selectedRows.value, ...currentPageRows];
const map = new Map();
allRows.forEach((row) => map.set(row[rowKey], row));
selectedRows.value = Array.from(map.values());
} else {
selectedRowKeys.value = selectedRowKeys.value.filter((key) => !currentPageKeys.includes(key));
selectedRows.value = selectedRows.value.filter((row) => !currentPageKeys.includes(row[rowKey]));
}
options.onSelectChange?.();
2025-07-15 17:45:16 +08:00
};
2025-09-05 10:39:01 +08:00
const onPageChange = (page: number, pageSize: number) => {
2025-09-04 23:30:41 +08:00
// console.log('onPageChange', page, pageSize);
2025-07-15 17:45:16 +08:00
pageInfo.value.page = page;
2025-09-04 23:30:41 +08:00
pageInfo.value.page_size = pageSize;
2025-07-15 17:45:16 +08:00
options.onPageChange?.(page);
};
2025-09-04 23:30:41 +08:00
const onPageSizeChange = (current: number, size: number) => {
// console.log('onPageSizeChange', current, size);
// pageInfo.value.page_size = size;
// pageInfo.value.page = 1;
// options.onPageSizeChange?.(size);
2025-07-15 17:45:16 +08:00
};
2025-07-21 12:01:32 +08:00
const resetPageInfo = () => {
2025-09-05 10:39:01 +08:00
pageInfo.value = cloneDeep(DEFAULT_PAGE_INFO);
};
2025-07-15 17:45:16 +08:00
const rowSelection = computed(() => ({
type: 'checkbox',
showCheckedAll: true,
2025-07-17 11:18:36 +08:00
width: 48,
2025-07-15 17:45:16 +08:00
}));
return {
selectedRowKeys,
selectedRows,
dataSource,
pageInfo,
onPageChange,
onPageSizeChange,
rowSelection,
handleSelect,
handleSelectAll,
resetPageInfo,
2025-07-17 15:28:20 +08:00
DEFAULT_PAGE_INFO,
2025-07-15 17:45:16 +08:00
};
}