forked from mengyxu/noob-components
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
102 lines
2.8 KiB
102 lines
2.8 KiB
|
3 months ago
|
# useListTable
|
||
|
|
|
||
|
|
> List/table management composable with pagination, search, and Element Plus integration.
|
||
|
|
|
||
|
|
## Purpose
|
||
|
|
|
||
|
|
Manages paginated table data with reactive search/filter parameters, automatic query on parameter changes, and column configuration support.
|
||
|
|
|
||
|
|
## Signature
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
export function useListTable(options: Options): {
|
||
|
|
rows: Record<string, any>;
|
||
|
|
example: Record<string, any>;
|
||
|
|
setRows: (resp?: Rows) => void;
|
||
|
|
setExample: (params: Record<string, any>) => void;
|
||
|
|
query: () => Promise<void>;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Options Interface
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
interface Options {
|
||
|
|
query: (example: any) => Promise<PageResponse<any> | Record<string, any>[] | undefined>;
|
||
|
|
initialPage?: number;
|
||
|
|
initialPageSize?: number;
|
||
|
|
initExample?: Record<string, any>;
|
||
|
|
disableAutoQuery?: boolean;
|
||
|
|
deep?: boolean;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Return Value
|
||
|
|
|
||
|
|
| Property | Type | Description |
|
||
|
|
|----------|------|-------------|
|
||
|
|
| `rows` | Reactive `Record<string, any>` | Table data (array or PageResponse with `total`) |
|
||
|
|
| `example` | Reactive `Record<string, any>` | Query parameters including `page` and `size` |
|
||
|
|
| `setRows` | `(resp?) => void` | Manually set table rows |
|
||
|
|
| `setExample` | `(params) => void` | Reset and set query parameters |
|
||
|
|
| `query` | `() => Promise<void>` | Manually trigger data fetch |
|
||
|
|
|
||
|
|
## TableColumn Interface
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
export interface TableColumn {
|
||
|
|
code: string;
|
||
|
|
name?: string;
|
||
|
|
i18n?: string;
|
||
|
|
type?: string;
|
||
|
|
width?: string | number;
|
||
|
|
fixed?: boolean | "left" | "right";
|
||
|
|
align?: "left" | "center" | "right";
|
||
|
|
slot?: boolean;
|
||
|
|
dict?: string;
|
||
|
|
timestamp?: boolean;
|
||
|
|
filesize?: boolean;
|
||
|
|
[others: string]: any;
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Usage Pattern
|
||
|
|
|
||
|
|
```typescript
|
||
|
|
// Example: plugs/composables/useListTable.ts
|
||
|
|
import { useListTable } from "plugs/composables";
|
||
|
|
|
||
|
|
const { rows, example, setExample, query } = useListTable({
|
||
|
|
query: fetchUserList,
|
||
|
|
initialPage: 1,
|
||
|
|
initialPageSize: 10,
|
||
|
|
initExample: { status: "active" },
|
||
|
|
});
|
||
|
|
|
||
|
|
// Modify query params and refetch
|
||
|
|
setExample({ page: 1, name: "john" });
|
||
|
|
|
||
|
|
// Manual query
|
||
|
|
await query();
|
||
|
|
```
|
||
|
|
|
||
|
|
## Key Implementation Details
|
||
|
|
|
||
|
|
1. **Pagination**: Uses `page` and `size` in `example` object
|
||
|
|
2. **Deep reactive**: When `deep: true`, uses `ref()` instead of `shallowRef()` for rows
|
||
|
|
3. **Auto-query**: Uses `watchEffect` to auto-refetch when `example` changes (unless `disableAutoQuery: true`)
|
||
|
|
4. **Row assignment**: `setRows` handles both array and `PageResponse` formats
|
||
|
|
5. **PageParams cleanup**: When response has no `total`, pagination params are removed from example
|
||
|
|
|
||
|
|
## Dependencies
|
||
|
|
|
||
|
|
- `@vueuse/core` - `toReactive`
|
||
|
|
- `plugs/element` - `showMessage`
|
||
|
|
- `vue3-i18n` - `useI18n`
|
||
|
|
- `noob-mengyxu/utils` - `clearAndAssign`, `deepCopy`
|
||
|
|
|
||
|
|
## Anti-patterns
|
||
|
|
|
||
|
|
- Do not manually mutate `rows` directly; use `setRows()`
|
||
|
|
- Avoid mixing array and PageResponse formats in same table
|