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; } const DEFAULT_PAGE_INFO = { page: 1, page_size: 20, total: 0, }; export function useTableSelectionWithPagination(options: UseTableSelectionWithPaginationOptions = {}) { const rowKey = options.rowKey || 'id'; const selectedRowKeys = ref>([]); const selectedRows = ref>([]); const pageInfo = ref(merge({}, DEFAULT_PAGE_INFO, options.pageInfo)); const dataSource = ref([]); // 单行选择 const handleSelect = (record: any, select: boolean) => { const _targetKey = record[rowKey]; if (select) { selectedRows.value.push(record); selectedRowKeys.value.push(_targetKey); } else { selectedRows.value = selectedRows.value.filter((v) => v[rowKey] !== _targetKey); selectedRowKeys.value = selectedRowKeys.value.filter((key) => key !== _targetKey); } options.onSelectChange?.(); }; // 全选/取消全选 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?.(); }; const onPageChange = (page: number, pageSize: number) => { // console.log('onPageChange', page, pageSize); pageInfo.value.page = page; pageInfo.value.page_size = pageSize; options.onPageChange?.(page); }; const onPageSizeChange = (current: number, size: number) => { // console.log('onPageSizeChange', current, size); // pageInfo.value.page_size = size; // pageInfo.value.page = 1; // options.onPageSizeChange?.(size); }; const resetPageInfo = () => { pageInfo.value = cloneDeep(DEFAULT_PAGE_INFO); }; const rowSelection = computed(() => ({ type: 'checkbox', showCheckedAll: true, width: 48, })); return { selectedRowKeys, selectedRows, dataSource, pageInfo, onPageChange, onPageSizeChange, rowSelection, handleSelect, handleSelectAll, resetPageInfo, DEFAULT_PAGE_INFO, }; }