feat: 封装表格分页hooks
This commit is contained in:
@ -21,7 +21,7 @@ export function configAutoImport() {
|
|||||||
'@vueuse/core',
|
'@vueuse/core',
|
||||||
{
|
{
|
||||||
dayjs: [['default', 'dayjs']],
|
dayjs: [['default', 'dayjs']],
|
||||||
'lodash-es': ['cloneDeep', 'omit', 'pick', 'union', 'uniq', 'isNumber', 'uniqBy', 'isEmpty'],
|
'lodash-es': ['cloneDeep', 'omit', 'pick', 'union', 'uniq', 'isNumber', 'uniqBy', 'isEmpty', 'merge'],
|
||||||
'@/hooks': ['useModal'],
|
'@/hooks': ['useModal'],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|||||||
87
src/hooks/useTableSelectionWithPagination.ts
Normal file
87
src/hooks/useTableSelectionWithPagination.ts
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
const DEFAULT_PAGE_INFO = {
|
||||||
|
page: 1,
|
||||||
|
pageSize: 20,
|
||||||
|
total: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function useTableSelectionWithPagination(options: UseTableSelectionWithPaginationOptions = {}) {
|
||||||
|
const rowKey = options.rowKey || 'id';
|
||||||
|
|
||||||
|
const selectedRowKeys = ref<Array<string | number>>([]);
|
||||||
|
const selectedRows = ref<any[]>([]);
|
||||||
|
|
||||||
|
const pageInfo = ref(merge({}, DEFAULT_PAGE_INFO, options.pageInfo));
|
||||||
|
|
||||||
|
const dataSource = ref<any[]>([]);
|
||||||
|
|
||||||
|
// 单行选择
|
||||||
|
const handleSelect = (selectedKeys: (string | number)[], rowKeyValue: string | number, record: any) => {
|
||||||
|
const select = selectedKeys.includes(rowKeyValue);
|
||||||
|
selectedRowKeys.value = selectedKeys;
|
||||||
|
|
||||||
|
if (select) {
|
||||||
|
if (!selectedRows.value.some((v) => v[rowKey] === record[rowKey])) {
|
||||||
|
selectedRows.value.push(record);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
selectedRows.value = selectedRows.value.filter((v) => v[rowKey] !== record[rowKey]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 全选/取消全选
|
||||||
|
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]));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onPageChange = (page: number) => {
|
||||||
|
pageInfo.value.page = page;
|
||||||
|
options.onPageChange?.(page);
|
||||||
|
};
|
||||||
|
const onPageSizeChange = (size: number) => {
|
||||||
|
pageInfo.value.page_size = size;
|
||||||
|
pageInfo.value.page = 1;
|
||||||
|
options.onPageSizeChange?.(size);
|
||||||
|
};
|
||||||
|
|
||||||
|
const rowSelection = computed(() => ({
|
||||||
|
type: 'checkbox',
|
||||||
|
showCheckedAll: true,
|
||||||
|
}));
|
||||||
|
|
||||||
|
return {
|
||||||
|
selectedRowKeys,
|
||||||
|
selectedRows,
|
||||||
|
dataSource,
|
||||||
|
pageInfo,
|
||||||
|
onPageChange,
|
||||||
|
onPageSizeChange,
|
||||||
|
rowSelection,
|
||||||
|
handleSelect,
|
||||||
|
handleSelectAll,
|
||||||
|
};
|
||||||
|
}
|
||||||
@ -44,16 +44,12 @@
|
|||||||
ref="tableRef"
|
ref="tableRef"
|
||||||
:data="dataSource"
|
:data="dataSource"
|
||||||
column-resizable
|
column-resizable
|
||||||
:row-selection="{
|
:row-selection="rowSelection"
|
||||||
type: 'checkbox',
|
:row-key="ROW_KEY"
|
||||||
showCheckedAll: true,
|
|
||||||
width: 48,
|
|
||||||
}"
|
|
||||||
row-key="account_id"
|
|
||||||
:selected-keys="selectedRowKeys"
|
|
||||||
:pagination="false"
|
:pagination="false"
|
||||||
:scroll="{ x: '100%', y: '100%' }"
|
:scroll="{ x: '100%', y: '100%' }"
|
||||||
class="w-100% flex-1 overflow-hidden"
|
class="w-100% flex-1 overflow-hidden"
|
||||||
|
:selected-keys="selectedRowKeys"
|
||||||
bordered
|
bordered
|
||||||
@select="handleSelect"
|
@select="handleSelect"
|
||||||
@select-all="handleSelectAll"
|
@select-all="handleSelectAll"
|
||||||
@ -97,7 +93,7 @@
|
|||||||
show-jumper
|
show-jumper
|
||||||
show-page-size
|
show-page-size
|
||||||
:current="pageInfo.page"
|
:current="pageInfo.page"
|
||||||
:page-size="pageInfo.pageSize"
|
:page-size="pageInfo.page_size"
|
||||||
@change="onPageChange"
|
@change="onPageChange"
|
||||||
@page-size-change="onPageSizeChange"
|
@page-size-change="onPageSizeChange"
|
||||||
/>
|
/>
|
||||||
@ -126,6 +122,7 @@
|
|||||||
import { INITIAL_FORM, INITIAL_PAGE_INFO, TABLE_COLUMNS } from './constants';
|
import { INITIAL_FORM, INITIAL_PAGE_INFO, TABLE_COLUMNS } from './constants';
|
||||||
import { formatTableField } from '@/utils/tools';
|
import { formatTableField } from '@/utils/tools';
|
||||||
import { postSubAccount, postAddSubAccount } from '@/api/all/propertyMarketing';
|
import { postSubAccount, postAddSubAccount } from '@/api/all/propertyMarketing';
|
||||||
|
import { useTableSelectionWithPagination } from '@/hooks/useTableSelectionWithPagination';
|
||||||
|
|
||||||
const emits = defineEmits('confirm');
|
const emits = defineEmits('confirm');
|
||||||
const update = inject('update');
|
const update = inject('update');
|
||||||
@ -133,13 +130,29 @@ const closeAddAccountModal = inject('closeAddAccountModal');
|
|||||||
const closeAuthorizeAccountModal = inject('closeAuthorizeAccountModal');
|
const closeAuthorizeAccountModal = inject('closeAuthorizeAccountModal');
|
||||||
|
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const dataSource = ref([]);
|
|
||||||
const query = ref(cloneDeep(INITIAL_FORM));
|
const query = ref(cloneDeep(INITIAL_FORM));
|
||||||
const pageInfo = ref(cloneDeep(INITIAL_PAGE_INFO));
|
|
||||||
const form = ref(null);
|
const form = ref(null);
|
||||||
|
|
||||||
const selectedAccounts = ref([]);
|
const ROW_KEY = 'account_id';
|
||||||
const selectedRowKeys = ref([]);
|
const {
|
||||||
|
selectedRowKeys,
|
||||||
|
selectedRows: selectedAccounts,
|
||||||
|
dataSource,
|
||||||
|
pageInfo,
|
||||||
|
onPageChange,
|
||||||
|
onPageSizeChange,
|
||||||
|
rowSelection,
|
||||||
|
handleSelect,
|
||||||
|
handleSelectAll,
|
||||||
|
} = useTableSelectionWithPagination({
|
||||||
|
rowKey: ROW_KEY,
|
||||||
|
onPageChange: () => {
|
||||||
|
getData();
|
||||||
|
},
|
||||||
|
onPageSizeChange: () => {
|
||||||
|
getData();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
const open = (formData) => {
|
const open = (formData) => {
|
||||||
const { platform, account, password } = formData;
|
const { platform, account, password } = formData;
|
||||||
@ -152,16 +165,15 @@ const open = (formData) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
getData();
|
getData();
|
||||||
|
|
||||||
visible.value = true;
|
visible.value = true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const onClose = () => {
|
const onClose = () => {
|
||||||
form.value = null;
|
form.value = null;
|
||||||
selectedAccounts.value = [];
|
selectedAccounts.value = [];
|
||||||
selectedRowKeys.value = [];
|
selectedRowKeys.value = [];
|
||||||
query.value = cloneDeep(INITIAL_FORM);
|
query.value = cloneDeep(INITIAL_FORM);
|
||||||
pageInfo.value = cloneDeep(INITIAL_PAGE_INFO);
|
pageInfo.value = cloneDeep(INITIAL_PAGE_INFO);
|
||||||
|
|
||||||
visible.value = false;
|
visible.value = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -181,12 +193,6 @@ const getData = async () => {
|
|||||||
...query.value,
|
...query.value,
|
||||||
page,
|
page,
|
||||||
page_size,
|
page_size,
|
||||||
// platform: 0,
|
|
||||||
// account: '543366265@qq.com',
|
|
||||||
// password: 'Xiaoti2025@',
|
|
||||||
// // page: 1,
|
|
||||||
// // page_size: 10,
|
|
||||||
// account_id: '',
|
|
||||||
});
|
});
|
||||||
if (code === 200) {
|
if (code === 200) {
|
||||||
dataSource.value = data?.data ?? [];
|
dataSource.value = data?.data ?? [];
|
||||||
@ -199,43 +205,6 @@ const reload = () => {
|
|||||||
getData();
|
getData();
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSelect = (selectedKeys, rowKey, record) => {
|
|
||||||
const select = selectedKeys.includes(rowKey);
|
|
||||||
selectedRowKeys.value = selectedKeys;
|
|
||||||
|
|
||||||
if (select) {
|
|
||||||
selectedAccounts.value.push(record);
|
|
||||||
} else {
|
|
||||||
selectedAccounts.value = selectedAccounts.value.filter((v) => v.account_id !== record.account_id);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleSelectAll = (checked) => {
|
|
||||||
const currentPageAccounts = dataSource.value;
|
|
||||||
const currentPageKeys = currentPageAccounts.map((v) => v.account_id);
|
|
||||||
|
|
||||||
if (checked) {
|
|
||||||
selectedRowKeys.value = Array.from(new Set([...selectedRowKeys.value, ...currentPageKeys]));
|
|
||||||
|
|
||||||
const allAccounts = [...selectedAccounts.value, ...currentPageAccounts];
|
|
||||||
const map = new Map();
|
|
||||||
allAccounts.forEach((acc) => map.set(acc.account_id, acc));
|
|
||||||
selectedAccounts.value = Array.from(map.values());
|
|
||||||
} else {
|
|
||||||
selectedRowKeys.value = selectedRowKeys.value.filter((key) => !currentPageKeys.includes(key));
|
|
||||||
selectedAccounts.value = selectedAccounts.value.filter((acc) => !currentPageKeys.includes(acc.account_id));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onPageChange = (current) => {
|
|
||||||
pageInfo.value.page = current;
|
|
||||||
getData();
|
|
||||||
};
|
|
||||||
const onPageSizeChange = (pageSize) => {
|
|
||||||
pageInfo.value.page_size = pageSize;
|
|
||||||
reload();
|
|
||||||
};
|
|
||||||
|
|
||||||
defineExpose({ open });
|
defineExpose({ open });
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user