aa
This commit is contained in:
@@ -4,17 +4,17 @@
|
||||
|
||||
### 1. 入参 `BasicTableProps`
|
||||
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| `createdIsNeed` | `boolean` | **true** | 是否在 `onMounted` 时自动请求列表 |
|
||||
| `isPage` | `boolean` | true | 是否分页 |
|
||||
| `queryForm` | `any` | `{}` | 查询条件,会合并到请求参数 |
|
||||
| `pageList` | `(...arg: any) => Promise<any>` | - | **必填**,分页接口方法 |
|
||||
| `props` | `object` | `{ item: 'records', totalCount: 'total' }` | 列表/总数的数据路径 |
|
||||
| `validate` | `Function` | - | 请求前校验,不通过则不请求 |
|
||||
| `onLoaded` | `Function` | - | 请求成功、写入 `dataList` 后的回调 |
|
||||
| `onCascaded` | `Function` | - | 级联回调 |
|
||||
| `pagination` | `Pagination` | 见源码 | 分页配置 |
|
||||
| 属性 | 类型 | 默认值 | 说明 |
|
||||
| --------------- | ------------------------------- | ------------------------------------------ | ---------------------------------- |
|
||||
| `createdIsNeed` | `boolean` | **true** | 是否在 `onMounted` 时自动请求列表 |
|
||||
| `isPage` | `boolean` | true | 是否分页 |
|
||||
| `queryForm` | `any` | `{}` | 查询条件,会合并到请求参数 |
|
||||
| `pageList` | `(...arg: any) => Promise<any>` | - | **必填**,分页接口方法 |
|
||||
| `props` | `object` | `{ item: 'records', totalCount: 'total' }` | 列表/总数的数据路径 |
|
||||
| `validate` | `Function` | - | 请求前校验,不通过则不请求 |
|
||||
| `onLoaded` | `Function` | - | 请求成功、写入 `dataList` 后的回调 |
|
||||
| `onCascaded` | `Function` | - | 级联回调 |
|
||||
| `pagination` | `Pagination` | 见源码 | 分页配置 |
|
||||
|
||||
### 2. 内部逻辑
|
||||
|
||||
@@ -27,12 +27,12 @@
|
||||
|
||||
```ts
|
||||
{
|
||||
getDataList, // (refresh?: any) => void,默认重置到第 1 页再请求;getDataList(false) 不重置页码
|
||||
currentChangeHandle, // 页码变化时调用
|
||||
sizeChangeHandle, // 每页条数变化时调用
|
||||
sortChangeHandle, // 排序变化时调用(若表格支持 sortable="custom")
|
||||
tableStyle, // { cellStyle, headerCellStyle }
|
||||
downBlobFile // 下载文件
|
||||
getDataList, // (refresh?: any) => void,默认重置到第 1 页再请求;getDataList(false) 不重置页码
|
||||
currentChangeHandle, // 页码变化时调用
|
||||
sizeChangeHandle, // 每页条数变化时调用
|
||||
sortChangeHandle, // 排序变化时调用(若表格支持 sortable="custom")
|
||||
tableStyle, // { cellStyle, headerCellStyle }
|
||||
downBlobFile; // 下载文件
|
||||
}
|
||||
```
|
||||
|
||||
@@ -43,17 +43,17 @@
|
||||
### 1. 定义 state 并传入 useTable
|
||||
|
||||
```ts
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
|
||||
const search = reactive({ deptCode: '', realName: '', teacherNo: '' })
|
||||
const search = reactive({ deptCode: '', realName: '', teacherNo: '' });
|
||||
|
||||
const state = reactive<BasicTableProps>({
|
||||
queryForm: search, // 与 search-form 的 :model 同一对象
|
||||
pageList: fetchList, // 或自定义方法合并额外参数
|
||||
// createdIsNeed 不写则默认为 true,首屏自动请求
|
||||
})
|
||||
queryForm: search, // 与 search-form 的 :model 同一对象
|
||||
pageList: fetchList, // 或自定义方法合并额外参数
|
||||
// createdIsNeed 不写则默认为 true,首屏自动请求
|
||||
});
|
||||
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTable(state);
|
||||
```
|
||||
|
||||
- **state 由调用方定义并传入**,不要在解构时期望 `useTable` 返回 `state`(源码未返回)。
|
||||
@@ -78,18 +78,18 @@ const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle } = useTa
|
||||
|
||||
## 三、professionaltitlerelation/index.vue 检查结果
|
||||
|
||||
| 检查项 | 状态 | 说明 |
|
||||
|--------|------|------|
|
||||
| queryForm 使用 search | ✅ | 与 search-form 的 model 一致 |
|
||||
| pageList 返回结构 | ✅ | 返回 `{ data: { records, total } }`,与默认 props 一致 |
|
||||
| createdIsNeed | ✅ | 未配置即默认 true,首屏由 useTable 自动请求 |
|
||||
| onMounted 不重复请求 | ✅ | 仅 `loadDictData()`,未再调 getDataList |
|
||||
| 表格绑定 state.dataList / state.loading | ✅ | 正确 |
|
||||
| 分页绑定 state.pagination + currentChangeHandle/sizeChangeHandle | ✅ | 正确 |
|
||||
| 查询 handleFilter → getDataList() | ✅ | 正确 |
|
||||
| 重置 resetQuery → 清空 search + getDataList() | ✅ | 正确 |
|
||||
| 删除/审核后 getDataList() | ✅ | 正确 |
|
||||
| tableStyle 用于 el-table | ✅ | 正确 |
|
||||
| 检查项 | 状态 | 说明 |
|
||||
| ---------------------------------------------------------------- | ---- | ------------------------------------------------------ |
|
||||
| queryForm 使用 search | ✅ | 与 search-form 的 model 一致 |
|
||||
| pageList 返回结构 | ✅ | 返回 `{ data: { records, total } }`,与默认 props 一致 |
|
||||
| createdIsNeed | ✅ | 未配置即默认 true,首屏由 useTable 自动请求 |
|
||||
| onMounted 不重复请求 | ✅ | 仅 `loadDictData()`,未再调 getDataList |
|
||||
| 表格绑定 state.dataList / state.loading | ✅ | 正确 |
|
||||
| 分页绑定 state.pagination + currentChangeHandle/sizeChangeHandle | ✅ | 正确 |
|
||||
| 查询 handleFilter → getDataList() | ✅ | 正确 |
|
||||
| 重置 resetQuery → 清空 search + getDataList() | ✅ | 正确 |
|
||||
| 删除/审核后 getDataList() | ✅ | 正确 |
|
||||
| tableStyle 用于 el-table | ✅ | 正确 |
|
||||
|
||||
**结论**:当前 `professionaltitlerelation/index.vue` 对 hooks/table 的使用符合上述规范,无需修改。
|
||||
|
||||
|
||||
1158
docs/hooks使用指南.md
1158
docs/hooks使用指南.md
File diff suppressed because it is too large
Load Diff
@@ -5,6 +5,7 @@
|
||||
`useTableColumnControl` 是一个用于统一管理表格列显示/隐藏和排序功能的 Vue 3 Composition API Hook。它封装了列配置的加载、保存、同步等逻辑,让开发者只需几行代码即可实现完整的表格列控制功能。
|
||||
|
||||
### 主要功能
|
||||
|
||||
- ✅ 列显示/隐藏控制
|
||||
- ✅ 列排序管理
|
||||
- ✅ 配置自动保存到本地存储
|
||||
@@ -17,13 +18,15 @@
|
||||
## 二、安装和引入
|
||||
|
||||
### 文件位置
|
||||
|
||||
```
|
||||
src/hooks/tableColumn.ts
|
||||
```
|
||||
|
||||
### 引入方式
|
||||
|
||||
```typescript
|
||||
import { useTableColumnControl, type TableColumn } from '/@/hooks/tableColumn'
|
||||
import { useTableColumnControl, type TableColumn } from '/@/hooks/tableColumn';
|
||||
```
|
||||
|
||||
---
|
||||
@@ -43,102 +46,96 @@ import { useTableColumnControl, type TableColumn } from '/@/hooks/tableColumn'
|
||||
### 2. 定义表格列配置
|
||||
|
||||
```typescript
|
||||
import { User, Calendar, Phone } from '@element-plus/icons-vue'
|
||||
import { User, Calendar, Phone } from '@element-plus/icons-vue';
|
||||
|
||||
const tableColumns = [
|
||||
{ prop: 'name', label: '姓名', icon: User },
|
||||
{ prop: 'age', label: '年龄', icon: Calendar },
|
||||
{ prop: 'phone', label: '电话', icon: Phone }
|
||||
]
|
||||
{ prop: 'name', label: '姓名', icon: User },
|
||||
{ prop: 'age', label: '年龄', icon: Calendar },
|
||||
{ prop: 'phone', label: '电话', icon: Phone },
|
||||
];
|
||||
```
|
||||
|
||||
### 3. 使用 Hook
|
||||
|
||||
```typescript
|
||||
const {
|
||||
visibleColumns,
|
||||
visibleColumnsSorted,
|
||||
checkColumnVisible,
|
||||
handleColumnChange,
|
||||
handleColumnOrderChange
|
||||
} = useTableColumnControl(tableColumns)
|
||||
const { visibleColumns, visibleColumnsSorted, checkColumnVisible, handleColumnChange, handleColumnOrderChange } = useTableColumnControl(tableColumns);
|
||||
```
|
||||
|
||||
### 4. 在模板中使用
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div class="modern-page-container">
|
||||
<div class="page-wrapper">
|
||||
<!-- 搜索表单卡片 -->
|
||||
<el-card v-show="showSearch" class="search-card" shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon class="title-icon"><Search /></el-icon>
|
||||
筛选条件
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-form class="search-form">
|
||||
<!-- 搜索表单项 -->
|
||||
</el-form>
|
||||
</el-card>
|
||||
<div class="modern-page-container">
|
||||
<div class="page-wrapper">
|
||||
<!-- 搜索表单卡片 -->
|
||||
<el-card v-show="showSearch" class="search-card" shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon class="title-icon"><Search /></el-icon>
|
||||
筛选条件
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
<el-form class="search-form">
|
||||
<!-- 搜索表单项 -->
|
||||
</el-form>
|
||||
</el-card>
|
||||
|
||||
<!-- 内容卡片 -->
|
||||
<el-card class="content-card" shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon class="title-icon"><Document /></el-icon>
|
||||
数据列表
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<!-- TableColumnControl 组件 -->
|
||||
<TableColumnControl
|
||||
:columns="tableColumns"
|
||||
v-model="visibleColumns"
|
||||
@change="handleColumnChange"
|
||||
@order-change="handleColumnOrderChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<!-- 内容卡片 -->
|
||||
<el-card class="content-card" shadow="never">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span class="card-title">
|
||||
<el-icon class="title-icon"><Document /></el-icon>
|
||||
数据列表
|
||||
</span>
|
||||
<div class="header-actions">
|
||||
<!-- TableColumnControl 组件 -->
|
||||
<TableColumnControl
|
||||
:columns="tableColumns"
|
||||
v-model="visibleColumns"
|
||||
@change="handleColumnChange"
|
||||
@order-change="handleColumnOrderChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table :data="dataList" stripe class="modern-table">
|
||||
<el-table-column type="index" label="序号" width="70">
|
||||
<template #default="{ $index }">
|
||||
{{ $index + 1 + ((pagination?.current || 1) - 1) * (pagination?.size || 10) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 动态渲染列 -->
|
||||
<template v-for="col in visibleColumnsSorted" :key="col.prop">
|
||||
<el-table-column
|
||||
v-if="checkColumnVisible(col.prop || '')"
|
||||
:prop="col.prop"
|
||||
:label="col.label"
|
||||
:width="col.width"
|
||||
:min-width="col.minWidth"
|
||||
>
|
||||
<template #header>
|
||||
<el-icon v-if="col.icon">
|
||||
<component :is="col.icon" />
|
||||
</el-icon>
|
||||
<span style="margin-left: 4px">{{ col.label }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table :data="dataList" stripe class="modern-table">
|
||||
<el-table-column type="index" label="序号" width="70">
|
||||
<template #default="{ $index }">
|
||||
{{ $index + 1 + ((pagination?.current || 1) - 1) * (pagination?.size || 10) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-wrapper">
|
||||
<pagination v-bind="pagination" />
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 动态渲染列 -->
|
||||
<template v-for="col in visibleColumnsSorted" :key="col.prop">
|
||||
<el-table-column
|
||||
v-if="checkColumnVisible(col.prop || '')"
|
||||
:prop="col.prop"
|
||||
:label="col.label"
|
||||
:width="col.width"
|
||||
:min-width="col.minWidth"
|
||||
>
|
||||
<template #header>
|
||||
<el-icon v-if="col.icon">
|
||||
<component :is="col.icon" />
|
||||
</el-icon>
|
||||
<span style="margin-left: 4px">{{ col.label }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-wrapper">
|
||||
<pagination v-bind="pagination" />
|
||||
</div>
|
||||
</el-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
```
|
||||
|
||||
@@ -148,86 +145,80 @@ const {
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<div>
|
||||
<right-toolbar>
|
||||
<TableColumnControl
|
||||
ref="columnControlRef"
|
||||
:columns="tableColumns"
|
||||
v-model="visibleColumns"
|
||||
trigger-type="default"
|
||||
trigger-circle
|
||||
@change="handleColumnChange"
|
||||
@order-change="handleColumnOrderChange"
|
||||
>
|
||||
<template #trigger>
|
||||
<el-tooltip content="列设置" placement="top">
|
||||
<el-button circle>
|
||||
<el-icon><Menu /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</TableColumnControl>
|
||||
</right-toolbar>
|
||||
<div>
|
||||
<right-toolbar>
|
||||
<TableColumnControl
|
||||
ref="columnControlRef"
|
||||
:columns="tableColumns"
|
||||
v-model="visibleColumns"
|
||||
trigger-type="default"
|
||||
trigger-circle
|
||||
@change="handleColumnChange"
|
||||
@order-change="handleColumnOrderChange"
|
||||
>
|
||||
<template #trigger>
|
||||
<el-tooltip content="列设置" placement="top">
|
||||
<el-button circle>
|
||||
<el-icon><Menu /></el-icon>
|
||||
</el-button>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</TableColumnControl>
|
||||
</right-toolbar>
|
||||
|
||||
<el-table :data="state.dataList" stripe>
|
||||
<el-table-column type="index" label="序号" width="70">
|
||||
<template #default="{ $index }">
|
||||
{{ $index + 1 + ((state.pagination?.current || 1) - 1) * (state.pagination?.size || 10) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table :data="state.dataList" stripe>
|
||||
<el-table-column type="index" label="序号" width="70">
|
||||
<template #default="{ $index }">
|
||||
{{ $index + 1 + ((state.pagination?.current || 1) - 1) * (state.pagination?.size || 10) }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
|
||||
<template v-for="col in visibleColumnsSorted" :key="col.prop">
|
||||
<el-table-column
|
||||
v-if="checkColumnVisible(col.prop || '')"
|
||||
:prop="col.prop"
|
||||
:label="col.label"
|
||||
:width="col.width"
|
||||
:min-width="col.minWidth"
|
||||
show-overflow-tooltip
|
||||
>
|
||||
<template #header>
|
||||
<el-icon v-if="col.icon">
|
||||
<component :is="col.icon" />
|
||||
</el-icon>
|
||||
<span style="margin-left: 4px">{{ col.label }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
<template v-for="col in visibleColumnsSorted" :key="col.prop">
|
||||
<el-table-column
|
||||
v-if="checkColumnVisible(col.prop || '')"
|
||||
:prop="col.prop"
|
||||
:label="col.label"
|
||||
:width="col.width"
|
||||
:min-width="col.minWidth"
|
||||
show-overflow-tooltip
|
||||
>
|
||||
<template #header>
|
||||
<el-icon v-if="col.icon">
|
||||
<component :is="col.icon" />
|
||||
</el-icon>
|
||||
<span style="margin-left: 4px">{{ col.label }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
|
||||
<el-table-column label="操作" width="180" fixed="right">
|
||||
<!-- 操作列内容 -->
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
<el-table-column label="操作" width="180" fixed="right">
|
||||
<!-- 操作列内容 -->
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref } from 'vue'
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn'
|
||||
import { User, Calendar, Phone, Menu } from '@element-plus/icons-vue'
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue'
|
||||
import { ref } from 'vue';
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn';
|
||||
import { User, Calendar, Phone, Menu } from '@element-plus/icons-vue';
|
||||
import TableColumnControl from '/@/components/TableColumnControl/index.vue';
|
||||
|
||||
// 定义表格列
|
||||
const tableColumns = [
|
||||
{ prop: 'name', label: '姓名', icon: User },
|
||||
{ prop: 'age', label: '年龄', icon: Calendar },
|
||||
{ prop: 'phone', label: '电话', icon: Phone }
|
||||
]
|
||||
{ prop: 'name', label: '姓名', icon: User },
|
||||
{ prop: 'age', label: '年龄', icon: Calendar },
|
||||
{ prop: 'phone', label: '电话', icon: Phone },
|
||||
];
|
||||
|
||||
// 使用 Hook
|
||||
const {
|
||||
visibleColumns,
|
||||
visibleColumnsSorted,
|
||||
checkColumnVisible,
|
||||
handleColumnChange,
|
||||
handleColumnOrderChange
|
||||
} = useTableColumnControl(tableColumns)
|
||||
const { visibleColumns, visibleColumnsSorted, checkColumnVisible, handleColumnChange, handleColumnOrderChange } = useTableColumnControl(tableColumns);
|
||||
|
||||
const columnControlRef = ref()
|
||||
const columnControlRef = ref();
|
||||
const state = ref({
|
||||
dataList: [],
|
||||
pagination: { current: 1, size: 10 }
|
||||
})
|
||||
dataList: [],
|
||||
pagination: { current: 1, size: 10 },
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -239,37 +230,37 @@ const state = ref({
|
||||
|
||||
```typescript
|
||||
interface TableColumn {
|
||||
prop?: string // 列属性名
|
||||
label?: string // 列标题
|
||||
icon?: any // 列图标组件
|
||||
width?: number | string // 列宽度
|
||||
minWidth?: number | string // 最小宽度
|
||||
showOverflowTooltip?: boolean // 是否显示溢出提示
|
||||
align?: 'left' | 'center' | 'right' // 对齐方式
|
||||
alwaysShow?: boolean // 是否始终显示(不参与列控制)
|
||||
fixed?: boolean | 'left' | 'right' // 是否固定列
|
||||
[key: string]: any // 其他自定义属性
|
||||
prop?: string; // 列属性名
|
||||
label?: string; // 列标题
|
||||
icon?: any; // 列图标组件
|
||||
width?: number | string; // 列宽度
|
||||
minWidth?: number | string; // 最小宽度
|
||||
showOverflowTooltip?: boolean; // 是否显示溢出提示
|
||||
align?: 'left' | 'center' | 'right'; // 对齐方式
|
||||
alwaysShow?: boolean; // 是否始终显示(不参与列控制)
|
||||
fixed?: boolean | 'left' | 'right'; // 是否固定列
|
||||
[key: string]: any; // 其他自定义属性
|
||||
}
|
||||
```
|
||||
|
||||
### Hook 返回值
|
||||
|
||||
| 属性/方法 | 类型 | 说明 |
|
||||
|----------|------|------|
|
||||
| `visibleColumns` | `Ref<string[]>` | 当前可见的列 key 数组 |
|
||||
| `columnOrder` | `Ref<string[]>` | 列排序顺序数组 |
|
||||
| `visibleColumnsSorted` | `ComputedRef<TableColumn[]>` | 排序后的可见列配置数组 |
|
||||
| `checkColumnVisible` | `(prop: string) => boolean` | 检查列是否可见 |
|
||||
| `handleColumnChange` | `(value: string[]) => void` | 处理列显示变化 |
|
||||
| `handleColumnOrderChange` | `(order: string[]) => void` | 处理列排序变化 |
|
||||
| `loadSavedConfig` | `() => void` | 手动加载保存的配置 |
|
||||
| 属性/方法 | 类型 | 说明 |
|
||||
| ------------------------- | ---------------------------- | ---------------------- |
|
||||
| `visibleColumns` | `Ref<string[]>` | 当前可见的列 key 数组 |
|
||||
| `columnOrder` | `Ref<string[]>` | 列排序顺序数组 |
|
||||
| `visibleColumnsSorted` | `ComputedRef<TableColumn[]>` | 排序后的可见列配置数组 |
|
||||
| `checkColumnVisible` | `(prop: string) => boolean` | 检查列是否可见 |
|
||||
| `handleColumnChange` | `(value: string[]) => void` | 处理列显示变化 |
|
||||
| `handleColumnOrderChange` | `(order: string[]) => void` | 处理列排序变化 |
|
||||
| `loadSavedConfig` | `() => void` | 手动加载保存的配置 |
|
||||
|
||||
### Hook 选项参数
|
||||
|
||||
```typescript
|
||||
interface Options {
|
||||
autoLoad?: boolean // 是否自动加载配置,默认 true
|
||||
storageKey?: string // 自定义存储 key,默认使用路由路径
|
||||
autoLoad?: boolean; // 是否自动加载配置,默认 true
|
||||
storageKey?: string; // 自定义存储 key,默认使用路由路径
|
||||
}
|
||||
```
|
||||
|
||||
@@ -282,15 +273,12 @@ interface Options {
|
||||
如果不想使用默认的路由路径作为存储 key,可以自定义:
|
||||
|
||||
```typescript
|
||||
const {
|
||||
visibleColumns,
|
||||
visibleColumnsSorted,
|
||||
checkColumnVisible,
|
||||
handleColumnChange,
|
||||
handleColumnOrderChange
|
||||
} = useTableColumnControl(tableColumns, {
|
||||
storageKey: 'custom-table-columns-key'
|
||||
})
|
||||
const { visibleColumns, visibleColumnsSorted, checkColumnVisible, handleColumnChange, handleColumnOrderChange } = useTableColumnControl(
|
||||
tableColumns,
|
||||
{
|
||||
storageKey: 'custom-table-columns-key',
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
### 2. 禁用自动加载
|
||||
@@ -298,21 +286,15 @@ const {
|
||||
如果需要在特定时机手动加载配置:
|
||||
|
||||
```typescript
|
||||
const {
|
||||
visibleColumns,
|
||||
visibleColumnsSorted,
|
||||
checkColumnVisible,
|
||||
handleColumnChange,
|
||||
handleColumnOrderChange,
|
||||
loadSavedConfig
|
||||
} = useTableColumnControl(tableColumns, {
|
||||
autoLoad: false
|
||||
})
|
||||
const { visibleColumns, visibleColumnsSorted, checkColumnVisible, handleColumnChange, handleColumnOrderChange, loadSavedConfig } =
|
||||
useTableColumnControl(tableColumns, {
|
||||
autoLoad: false,
|
||||
});
|
||||
|
||||
// 在需要的时候手动加载
|
||||
onMounted(() => {
|
||||
loadSavedConfig()
|
||||
})
|
||||
loadSavedConfig();
|
||||
});
|
||||
```
|
||||
|
||||
### 3. 固定列和始终显示的列
|
||||
@@ -321,15 +303,15 @@ onMounted(() => {
|
||||
|
||||
```typescript
|
||||
const tableColumns = [
|
||||
{ prop: 'name', label: '姓名', icon: User },
|
||||
{ prop: 'age', label: '年龄', icon: Calendar },
|
||||
{
|
||||
prop: 'action',
|
||||
label: '操作',
|
||||
alwaysShow: true, // 始终显示
|
||||
fixed: 'right' // 固定在右侧
|
||||
}
|
||||
]
|
||||
{ prop: 'name', label: '姓名', icon: User },
|
||||
{ prop: 'age', label: '年龄', icon: Calendar },
|
||||
{
|
||||
prop: 'action',
|
||||
label: '操作',
|
||||
alwaysShow: true, // 始终显示
|
||||
fixed: 'right', // 固定在右侧
|
||||
},
|
||||
];
|
||||
```
|
||||
|
||||
### 4. 特殊列模板
|
||||
@@ -338,23 +320,19 @@ const tableColumns = [
|
||||
|
||||
```vue
|
||||
<template v-for="col in visibleColumnsSorted" :key="col.prop">
|
||||
<el-table-column
|
||||
v-if="checkColumnVisible(col.prop || '')"
|
||||
:prop="col.prop"
|
||||
:label="col.label"
|
||||
>
|
||||
<!-- 状态列特殊模板 -->
|
||||
<template v-if="col.prop === 'status'" #default="scope">
|
||||
<el-tag :type="scope.row.status === '1' ? 'success' : 'warning'">
|
||||
{{ scope.row.status }}
|
||||
</el-tag>
|
||||
</template>
|
||||
|
||||
<!-- 其他列默认显示 -->
|
||||
<template v-else #default="scope">
|
||||
{{ scope.row[col.prop] }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column v-if="checkColumnVisible(col.prop || '')" :prop="col.prop" :label="col.label">
|
||||
<!-- 状态列特殊模板 -->
|
||||
<template v-if="col.prop === 'status'" #default="scope">
|
||||
<el-tag :type="scope.row.status === '1' ? 'success' : 'warning'">
|
||||
{{ scope.row.status }}
|
||||
</el-tag>
|
||||
</template>
|
||||
|
||||
<!-- 其他列默认显示 -->
|
||||
<template v-else #default="scope">
|
||||
{{ scope.row[col.prop] }}
|
||||
</template>
|
||||
</el-table-column>
|
||||
</template>
|
||||
```
|
||||
|
||||
@@ -369,15 +347,12 @@ const tableColumns = [
|
||||
```typescript
|
||||
// ✅ 正确
|
||||
const tableColumns = [
|
||||
{ prop: 'name', label: '姓名' },
|
||||
{ prop: 'age', label: '年龄' }
|
||||
]
|
||||
{ prop: 'name', label: '姓名' },
|
||||
{ prop: 'age', label: '年龄' },
|
||||
];
|
||||
|
||||
// ❌ 错误:两个列都没有 prop
|
||||
const tableColumns = [
|
||||
{ label: '姓名' },
|
||||
{ label: '年龄' }
|
||||
]
|
||||
const tableColumns = [{ label: '姓名' }, { label: '年龄' }];
|
||||
```
|
||||
|
||||
### 2. 响应式更新
|
||||
@@ -386,12 +361,12 @@ const tableColumns = [
|
||||
|
||||
```typescript
|
||||
const tableColumns = ref([
|
||||
{ prop: 'name', label: '姓名' },
|
||||
{ prop: 'age', label: '年龄' }
|
||||
])
|
||||
{ prop: 'name', label: '姓名' },
|
||||
{ prop: 'age', label: '年龄' },
|
||||
]);
|
||||
|
||||
// 动态添加列
|
||||
tableColumns.value.push({ prop: 'phone', label: '电话' })
|
||||
tableColumns.value.push({ prop: 'phone', label: '电话' });
|
||||
```
|
||||
|
||||
### 3. 配置存储位置
|
||||
@@ -405,12 +380,15 @@ tableColumns.value.push({ prop: 'phone', label: '电话' })
|
||||
Hook 默认在组件挂载时自动加载配置。如果需要在数据加载后重新加载:
|
||||
|
||||
```typescript
|
||||
const { loadSavedConfig } = useTableColumnControl(tableColumns)
|
||||
const { loadSavedConfig } = useTableColumnControl(tableColumns);
|
||||
|
||||
watch(() => someData.value, () => {
|
||||
// 数据变化后重新加载配置
|
||||
loadSavedConfig()
|
||||
})
|
||||
watch(
|
||||
() => someData.value,
|
||||
() => {
|
||||
// 数据变化后重新加载配置
|
||||
loadSavedConfig();
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
---
|
||||
@@ -424,23 +402,23 @@ watch(() => someData.value, () => {
|
||||
```typescript
|
||||
// 扩展 Hook
|
||||
function useTableColumnControlWithWidth(tableColumns: TableColumn[]) {
|
||||
const baseHook = useTableColumnControl(tableColumns)
|
||||
const columnWidths = ref<Record<string, number>>({})
|
||||
const baseHook = useTableColumnControl(tableColumns);
|
||||
const columnWidths = ref<Record<string, number>>({});
|
||||
|
||||
const handleColumnWidthChange = (prop: string, width: number) => {
|
||||
columnWidths.value[prop] = width
|
||||
// 保存到本地存储
|
||||
const storageKey = getStorageKey()
|
||||
const config = getTableConfigFromLocal(storageKey) || {}
|
||||
config.columnWidths = columnWidths.value
|
||||
saveTableConfigToLocal(storageKey, config)
|
||||
}
|
||||
const handleColumnWidthChange = (prop: string, width: number) => {
|
||||
columnWidths.value[prop] = width;
|
||||
// 保存到本地存储
|
||||
const storageKey = getStorageKey();
|
||||
const config = getTableConfigFromLocal(storageKey) || {};
|
||||
config.columnWidths = columnWidths.value;
|
||||
saveTableConfigToLocal(storageKey, config);
|
||||
};
|
||||
|
||||
return {
|
||||
...baseHook,
|
||||
columnWidths,
|
||||
handleColumnWidthChange
|
||||
}
|
||||
return {
|
||||
...baseHook,
|
||||
columnWidths,
|
||||
handleColumnWidthChange,
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
@@ -450,24 +428,24 @@ function useTableColumnControlWithWidth(tableColumns: TableColumn[]) {
|
||||
|
||||
```typescript
|
||||
function useTableColumnControlWithFixed(tableColumns: TableColumn[]) {
|
||||
const baseHook = useTableColumnControl(tableColumns)
|
||||
const fixedColumns = ref<string[]>([])
|
||||
const baseHook = useTableColumnControl(tableColumns);
|
||||
const fixedColumns = ref<string[]>([]);
|
||||
|
||||
const toggleColumnFixed = (prop: string) => {
|
||||
const index = fixedColumns.value.indexOf(prop)
|
||||
if (index > -1) {
|
||||
fixedColumns.value.splice(index, 1)
|
||||
} else {
|
||||
fixedColumns.value.push(prop)
|
||||
}
|
||||
// 保存配置
|
||||
}
|
||||
const toggleColumnFixed = (prop: string) => {
|
||||
const index = fixedColumns.value.indexOf(prop);
|
||||
if (index > -1) {
|
||||
fixedColumns.value.splice(index, 1);
|
||||
} else {
|
||||
fixedColumns.value.push(prop);
|
||||
}
|
||||
// 保存配置
|
||||
};
|
||||
|
||||
return {
|
||||
...baseHook,
|
||||
fixedColumns,
|
||||
toggleColumnFixed
|
||||
}
|
||||
return {
|
||||
...baseHook,
|
||||
fixedColumns,
|
||||
toggleColumnFixed,
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
@@ -476,22 +454,17 @@ function useTableColumnControlWithFixed(tableColumns: TableColumn[]) {
|
||||
如果需要按分组管理列:
|
||||
|
||||
```typescript
|
||||
function useTableColumnControlWithGroup(
|
||||
tableColumns: TableColumn[],
|
||||
groups: Record<string, string[]>
|
||||
) {
|
||||
const baseHook = useTableColumnControl(tableColumns)
|
||||
|
||||
const getColumnsByGroup = (groupName: string) => {
|
||||
return tableColumns.filter(col =>
|
||||
groups[groupName]?.includes(col.prop || '')
|
||||
)
|
||||
}
|
||||
function useTableColumnControlWithGroup(tableColumns: TableColumn[], groups: Record<string, string[]>) {
|
||||
const baseHook = useTableColumnControl(tableColumns);
|
||||
|
||||
return {
|
||||
...baseHook,
|
||||
getColumnsByGroup
|
||||
}
|
||||
const getColumnsByGroup = (groupName: string) => {
|
||||
return tableColumns.filter((col) => groups[groupName]?.includes(col.prop || ''));
|
||||
};
|
||||
|
||||
return {
|
||||
...baseHook,
|
||||
getColumnsByGroup,
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
@@ -501,13 +474,13 @@ function useTableColumnControlWithGroup(
|
||||
|
||||
```typescript
|
||||
function useTableColumnControlWithCustomStorage(
|
||||
tableColumns: TableColumn[],
|
||||
storageAdapter: {
|
||||
get: (key: string) => Promise<any>
|
||||
set: (key: string, value: any) => Promise<void>
|
||||
}
|
||||
tableColumns: TableColumn[],
|
||||
storageAdapter: {
|
||||
get: (key: string) => Promise<any>;
|
||||
set: (key: string, value: any) => Promise<void>;
|
||||
}
|
||||
) {
|
||||
// 实现自定义存储逻辑
|
||||
// 实现自定义存储逻辑
|
||||
}
|
||||
```
|
||||
|
||||
@@ -518,6 +491,7 @@ function useTableColumnControlWithCustomStorage(
|
||||
### Q1: 为什么配置没有保存?
|
||||
|
||||
**A:** 检查以下几点:
|
||||
|
||||
1. 确保 `handleColumnChange` 和 `handleColumnOrderChange` 已正确绑定到组件
|
||||
2. 检查浏览器控制台是否有错误
|
||||
3. 确认 API 调用是否成功(检查网络请求)
|
||||
@@ -538,11 +512,11 @@ function useTableColumnControlWithCustomStorage(
|
||||
|
||||
```typescript
|
||||
// 清除本地存储
|
||||
localStorage.removeItem('user-table-configs-all')
|
||||
localStorage.removeItem('user-table-configs-all');
|
||||
|
||||
// 或通过 API 删除
|
||||
import { deleteUserTableConfig } from '/@/api/admin/usertable'
|
||||
deleteUserTableConfig(storageKey)
|
||||
import { deleteUserTableConfig } from '/@/api/admin/usertable';
|
||||
deleteUserTableConfig(storageKey);
|
||||
```
|
||||
|
||||
### Q4: 如何在多个页面共享列配置?
|
||||
@@ -551,8 +525,8 @@ deleteUserTableConfig(storageKey)
|
||||
|
||||
```typescript
|
||||
const { visibleColumns } = useTableColumnControl(tableColumns, {
|
||||
storageKey: 'shared-table-columns'
|
||||
})
|
||||
storageKey: 'shared-table-columns',
|
||||
});
|
||||
```
|
||||
|
||||
---
|
||||
@@ -565,12 +539,12 @@ const { visibleColumns } = useTableColumnControl(tableColumns, {
|
||||
|
||||
```typescript
|
||||
// src/views/xxx/columns.ts
|
||||
import { User, Calendar } from '@element-plus/icons-vue'
|
||||
import { User, Calendar } from '@element-plus/icons-vue';
|
||||
|
||||
export const tableColumns = [
|
||||
{ prop: 'name', label: '姓名', icon: User },
|
||||
{ prop: 'age', label: '年龄', icon: Calendar }
|
||||
]
|
||||
{ prop: 'name', label: '姓名', icon: User },
|
||||
{ prop: 'age', label: '年龄', icon: Calendar },
|
||||
];
|
||||
```
|
||||
|
||||
### 2. 类型定义
|
||||
@@ -578,11 +552,9 @@ export const tableColumns = [
|
||||
为列配置添加类型约束:
|
||||
|
||||
```typescript
|
||||
import type { TableColumn } from '/@/hooks/tableColumn'
|
||||
import type { TableColumn } from '/@/hooks/tableColumn';
|
||||
|
||||
const tableColumns: TableColumn[] = [
|
||||
{ prop: 'name', label: '姓名', icon: User }
|
||||
]
|
||||
const tableColumns: TableColumn[] = [{ prop: 'name', label: '姓名', icon: User }];
|
||||
```
|
||||
|
||||
### 3. 统一命名
|
||||
@@ -600,25 +572,25 @@ const tableColumns: TableColumn[] = [
|
||||
### 从旧实现迁移到 Hook
|
||||
|
||||
**旧代码(~90 行):**
|
||||
|
||||
```typescript
|
||||
const visibleColumns = ref<string[]>([])
|
||||
const columnOrder = ref<string[]>([])
|
||||
const loadSavedConfig = () => { /* ... */ }
|
||||
const handleColumnChange = () => { /* ... */ }
|
||||
const visibleColumns = ref<string[]>([]);
|
||||
const columnOrder = ref<string[]>([]);
|
||||
const loadSavedConfig = () => {
|
||||
/* ... */
|
||||
};
|
||||
const handleColumnChange = () => {
|
||||
/* ... */
|
||||
};
|
||||
// ... 更多代码
|
||||
```
|
||||
|
||||
**新代码(~5 行):**
|
||||
```typescript
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn'
|
||||
|
||||
const {
|
||||
visibleColumns,
|
||||
visibleColumnsSorted,
|
||||
checkColumnVisible,
|
||||
handleColumnChange,
|
||||
handleColumnOrderChange
|
||||
} = useTableColumnControl(tableColumns)
|
||||
```typescript
|
||||
import { useTableColumnControl } from '/@/hooks/tableColumn';
|
||||
|
||||
const { visibleColumns, visibleColumnsSorted, checkColumnVisible, handleColumnChange, handleColumnOrderChange } = useTableColumnControl(tableColumns);
|
||||
```
|
||||
|
||||
### 迁移步骤
|
||||
@@ -633,6 +605,7 @@ const {
|
||||
## 十二、更新日志
|
||||
|
||||
### v1.0.0 (2024-01-XX)
|
||||
|
||||
- ✅ 初始版本发布
|
||||
- ✅ 支持列显示/隐藏控制
|
||||
- ✅ 支持列排序管理
|
||||
@@ -653,6 +626,7 @@ const {
|
||||
## 十四、贡献指南
|
||||
|
||||
如果发现 bug 或有改进建议,请:
|
||||
|
||||
1. 提交 Issue 描述问题
|
||||
2. 提交 Pull Request 提供修复方案
|
||||
3. 更新本文档说明变更
|
||||
@@ -660,4 +634,3 @@ const {
|
||||
---
|
||||
|
||||
**最后更新:2024-01-XX**
|
||||
|
||||
|
||||
@@ -16,83 +16,77 @@
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<!-- 搜索表单 -->
|
||||
<search-form
|
||||
v-show="showSearch"
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter(search)"
|
||||
>
|
||||
<!-- 表单项 -->
|
||||
</search-form>
|
||||
<!-- 搜索表单 -->
|
||||
<search-form v-show="showSearch" :model="search" ref="searchFormRef" @keyup-enter="handleFilter(search)">
|
||||
<!-- 表单项 -->
|
||||
</search-form>
|
||||
|
||||
<!-- 表格 -->
|
||||
<el-table :data="tableData" v-loading="tableLoading">
|
||||
<!-- 表格列 -->
|
||||
</el-table>
|
||||
<!-- 表格 -->
|
||||
<el-table :data="tableData" v-loading="tableLoading">
|
||||
<!-- 表格列 -->
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 -->
|
||||
<pagination
|
||||
:current="page.currentPage"
|
||||
:size="page.pageSize"
|
||||
:total="page.total"
|
||||
@currentChange="currentChange"
|
||||
@sizeChange="handleSizeChange"
|
||||
/>
|
||||
<!-- 分页 -->
|
||||
<pagination :current="page.currentPage" :size="page.pageSize" :total="page.total" @currentChange="currentChange" @sizeChange="handleSizeChange" />
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
const search = reactive({
|
||||
deptCode: '',
|
||||
realName: '',
|
||||
teacherNo: '',
|
||||
// ... 其他字段
|
||||
})
|
||||
deptCode: '',
|
||||
realName: '',
|
||||
teacherNo: '',
|
||||
// ... 其他字段
|
||||
});
|
||||
|
||||
const tableData = ref([])
|
||||
const tableLoading = ref(false)
|
||||
const tableData = ref([]);
|
||||
const tableLoading = ref(false);
|
||||
const page = reactive({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
})
|
||||
const params = ref<any>({})
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0,
|
||||
});
|
||||
const params = ref<any>({});
|
||||
|
||||
// 手动实现数据加载
|
||||
const getList = (page: any) => {
|
||||
tableLoading.value = true
|
||||
fetchList(Object.assign({
|
||||
current: page.currentPage,
|
||||
size: page.pageSize
|
||||
}, params.value)).then((response: any) => {
|
||||
tableData.value = response.data.record.records
|
||||
page.total = response.data.record.total
|
||||
tableLoading.value = false
|
||||
})
|
||||
}
|
||||
tableLoading.value = true;
|
||||
fetchList(
|
||||
Object.assign(
|
||||
{
|
||||
current: page.currentPage,
|
||||
size: page.pageSize,
|
||||
},
|
||||
params.value
|
||||
)
|
||||
).then((response: any) => {
|
||||
tableData.value = response.data.record.records;
|
||||
page.total = response.data.record.total;
|
||||
tableLoading.value = false;
|
||||
});
|
||||
};
|
||||
|
||||
// 手动实现分页
|
||||
const currentChange = (val: number) => {
|
||||
page.currentPage = val
|
||||
getList(page)
|
||||
}
|
||||
page.currentPage = val;
|
||||
getList(page);
|
||||
};
|
||||
|
||||
const handleSizeChange = (val: number) => {
|
||||
page.pageSize = val
|
||||
page.currentPage = 1
|
||||
getList(page)
|
||||
}
|
||||
page.pageSize = val;
|
||||
page.currentPage = 1;
|
||||
getList(page);
|
||||
};
|
||||
|
||||
// 查询
|
||||
const handleFilter = (param: any) => {
|
||||
params.value = { ...param }
|
||||
page.currentPage = 1
|
||||
getList(page)
|
||||
}
|
||||
params.value = { ...param };
|
||||
page.currentPage = 1;
|
||||
getList(page);
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
getList(page)
|
||||
})
|
||||
getList(page);
|
||||
});
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -100,130 +94,114 @@ onMounted(() => {
|
||||
|
||||
```vue
|
||||
<template>
|
||||
<!-- 搜索表单 - 保持不变 -->
|
||||
<search-form
|
||||
v-show="showSearch"
|
||||
:model="search"
|
||||
ref="searchFormRef"
|
||||
@keyup-enter="handleFilter(search)"
|
||||
>
|
||||
<!-- 表单项 -->
|
||||
</search-form>
|
||||
<!-- 搜索表单 - 保持不变 -->
|
||||
<search-form v-show="showSearch" :model="search" ref="searchFormRef" @keyup-enter="handleFilter(search)">
|
||||
<!-- 表单项 -->
|
||||
</search-form>
|
||||
|
||||
<!-- 表格 - 使用 state.dataList 和 state.loading -->
|
||||
<el-table
|
||||
:data="state.dataList"
|
||||
v-loading="state.loading"
|
||||
:cell-style="tableStyle.cellStyle"
|
||||
:header-cell-style="tableStyle.headerCellStyle"
|
||||
>
|
||||
<!-- 表格列 -->
|
||||
</el-table>
|
||||
<!-- 表格 - 使用 state.dataList 和 state.loading -->
|
||||
<el-table :data="state.dataList" v-loading="state.loading" :cell-style="tableStyle.cellStyle" :header-cell-style="tableStyle.headerCellStyle">
|
||||
<!-- 表格列 -->
|
||||
</el-table>
|
||||
|
||||
<!-- 分页 - 使用 state.pagination -->
|
||||
<pagination
|
||||
:current="state.pagination.current"
|
||||
:size="state.pagination.size"
|
||||
:total="state.pagination.total"
|
||||
@currentChange="currentChangeHandle"
|
||||
@sizeChange="sizeChangeHandle"
|
||||
/>
|
||||
<!-- 分页 - 使用 state.pagination -->
|
||||
<pagination
|
||||
:current="state.pagination.current"
|
||||
:size="state.pagination.size"
|
||||
:total="state.pagination.total"
|
||||
@currentChange="currentChangeHandle"
|
||||
@sizeChange="sizeChangeHandle"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { fetchList } from '/@/api/professional/teacherbase'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
import { fetchList } from '/@/api/professional/teacherbase';
|
||||
|
||||
// 搜索表单数据 - 保持不变
|
||||
const search = reactive({
|
||||
deptCode: '',
|
||||
realName: '',
|
||||
teacherNo: '',
|
||||
// ... 其他字段
|
||||
})
|
||||
deptCode: '',
|
||||
realName: '',
|
||||
teacherNo: '',
|
||||
// ... 其他字段
|
||||
});
|
||||
|
||||
// 额外参数(如 flag 等)
|
||||
const params = ref<any>({})
|
||||
const params = ref<any>({});
|
||||
|
||||
// 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
// 将 search 对象作为 queryForm
|
||||
queryForm: search,
|
||||
|
||||
// 自定义 pageList 方法,合并额外参数
|
||||
pageList: async (queryParams: any) => {
|
||||
// 合并 search 和 params 中的额外参数
|
||||
return await fetchList({
|
||||
...queryParams,
|
||||
...params.value
|
||||
})
|
||||
},
|
||||
|
||||
// 数据属性映射(根据后端返回结构调整)
|
||||
props: {
|
||||
item: 'record.records', // 数据列表路径
|
||||
totalCount: 'record.total' // 总数字段路径
|
||||
},
|
||||
|
||||
// 数据加载完成后的回调
|
||||
onLoaded: async (state) => {
|
||||
// 数据转换逻辑
|
||||
state.dataList = convertDictData(state.dataList)
|
||||
|
||||
// 其他处理逻辑(如 auditAll)
|
||||
// ...
|
||||
}
|
||||
})
|
||||
// 将 search 对象作为 queryForm
|
||||
queryForm: search,
|
||||
|
||||
// 自定义 pageList 方法,合并额外参数
|
||||
pageList: async (queryParams: any) => {
|
||||
// 合并 search 和 params 中的额外参数
|
||||
return await fetchList({
|
||||
...queryParams,
|
||||
...params.value,
|
||||
});
|
||||
},
|
||||
|
||||
// 数据属性映射(根据后端返回结构调整)
|
||||
props: {
|
||||
item: 'record.records', // 数据列表路径
|
||||
totalCount: 'record.total', // 总数字段路径
|
||||
},
|
||||
|
||||
// 数据加载完成后的回调
|
||||
onLoaded: async (state) => {
|
||||
// 数据转换逻辑
|
||||
state.dataList = convertDictData(state.dataList);
|
||||
|
||||
// 其他处理逻辑(如 auditAll)
|
||||
// ...
|
||||
},
|
||||
});
|
||||
|
||||
// 使用 useTable Hook
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle,
|
||||
state
|
||||
} = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle, state } = useTable(state);
|
||||
|
||||
// 查询方法 - 简化
|
||||
const handleFilter = (param: any) => {
|
||||
// 更新额外参数
|
||||
params.value = { ...param }
|
||||
// 调用 getDataList 刷新数据(会自动跳转到第一页)
|
||||
getDataList()
|
||||
}
|
||||
// 更新额外参数
|
||||
params.value = { ...param };
|
||||
// 调用 getDataList 刷新数据(会自动跳转到第一页)
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
searchFormRef.value?.formRef?.resetFields()
|
||||
// 重置 search 对象
|
||||
Object.keys(search).forEach(key => {
|
||||
search[key] = ''
|
||||
})
|
||||
params.value = {}
|
||||
getDataList()
|
||||
}
|
||||
searchFormRef.value?.formRef?.resetFields();
|
||||
// 重置 search 对象
|
||||
Object.keys(search).forEach((key) => {
|
||||
search[key] = '';
|
||||
});
|
||||
params.value = {};
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 其他需要刷新表格的地方
|
||||
const handelQuickSeach = (val: any) => {
|
||||
params.value.flag = val
|
||||
getDataList() // 使用 getDataList 替代 getList(page)
|
||||
}
|
||||
params.value.flag = val;
|
||||
getDataList(); // 使用 getDataList 替代 getList(page)
|
||||
};
|
||||
|
||||
const updateInoutFlag = (row: any, val: any) => {
|
||||
const updateParams = {"teacherNo": row.teacherNo, "inoutFlag": val}
|
||||
messageBox.confirm('确认操作?').then(() => {
|
||||
updateInout(updateParams).then((res: any) => {
|
||||
message.success("修改成功")
|
||||
getDataList(false) // 刷新但保持当前页
|
||||
})
|
||||
})
|
||||
}
|
||||
const updateParams = { teacherNo: row.teacherNo, inoutFlag: val };
|
||||
messageBox.confirm('确认操作?').then(() => {
|
||||
updateInout(updateParams).then((res: any) => {
|
||||
message.success('修改成功');
|
||||
getDataList(false); // 刷新但保持当前页
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// 数据转换函数(保持不变)
|
||||
const convertDictData = (records: any[]) => {
|
||||
// ... 转换逻辑
|
||||
return records
|
||||
}
|
||||
// ... 转换逻辑
|
||||
return records;
|
||||
};
|
||||
</script>
|
||||
```
|
||||
|
||||
@@ -232,20 +210,20 @@ const convertDictData = (records: any[]) => {
|
||||
### 1. 导入 useTable
|
||||
|
||||
```typescript
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
```
|
||||
|
||||
### 2. 配置 state
|
||||
|
||||
```typescript
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: search, // 将 search 对象作为 queryForm
|
||||
pageList: fetchList, // 或自定义方法
|
||||
props: {
|
||||
item: 'record.records',
|
||||
totalCount: 'record.total'
|
||||
}
|
||||
})
|
||||
queryForm: search, // 将 search 对象作为 queryForm
|
||||
pageList: fetchList, // 或自定义方法
|
||||
props: {
|
||||
item: 'record.records',
|
||||
totalCount: 'record.total',
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### 3. 处理额外参数
|
||||
@@ -255,49 +233,49 @@ const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
#### 方式一:自定义 pageList 方法(推荐)
|
||||
|
||||
```typescript
|
||||
const params = ref<any>({})
|
||||
const params = ref<any>({});
|
||||
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: search,
|
||||
pageList: async (queryParams: any) => {
|
||||
// 合并额外参数
|
||||
return await fetchList({
|
||||
...queryParams,
|
||||
...params.value // 合并额外参数
|
||||
})
|
||||
}
|
||||
})
|
||||
queryForm: search,
|
||||
pageList: async (queryParams: any) => {
|
||||
// 合并额外参数
|
||||
return await fetchList({
|
||||
...queryParams,
|
||||
...params.value, // 合并额外参数
|
||||
});
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
#### 方式二:在 onLoaded 中处理
|
||||
|
||||
```typescript
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: search,
|
||||
pageList: fetchList,
|
||||
onLoaded: async (state) => {
|
||||
// 可以在这里处理数据转换等逻辑
|
||||
}
|
||||
})
|
||||
queryForm: search,
|
||||
pageList: fetchList,
|
||||
onLoaded: async (state) => {
|
||||
// 可以在这里处理数据转换等逻辑
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
### 4. 替换数据引用
|
||||
|
||||
| 原代码 | 改造后 |
|
||||
|--------|--------|
|
||||
| `tableData` | `state.dataList` |
|
||||
| `tableLoading` | `state.loading` |
|
||||
| 原代码 | 改造后 |
|
||||
| ------------------ | -------------------------- |
|
||||
| `tableData` | `state.dataList` |
|
||||
| `tableLoading` | `state.loading` |
|
||||
| `page.currentPage` | `state.pagination.current` |
|
||||
| `page.pageSize` | `state.pagination.size` |
|
||||
| `page.total` | `state.pagination.total` |
|
||||
| `page.pageSize` | `state.pagination.size` |
|
||||
| `page.total` | `state.pagination.total` |
|
||||
|
||||
### 5. 替换方法调用
|
||||
|
||||
| 原代码 | 改造后 |
|
||||
|--------|--------|
|
||||
| `getList(page)` | `getDataList()` 或 `getDataList(false)` |
|
||||
| `currentChange(val)` | `currentChangeHandle(val)` |
|
||||
| `handleSizeChange(val)` | `sizeChangeHandle(val)` |
|
||||
| 原代码 | 改造后 |
|
||||
| ----------------------- | --------------------------------------- |
|
||||
| `getList(page)` | `getDataList()` 或 `getDataList(false)` |
|
||||
| `currentChange(val)` | `currentChangeHandle(val)` |
|
||||
| `handleSizeChange(val)` | `sizeChangeHandle(val)` |
|
||||
|
||||
### 6. 处理数据转换
|
||||
|
||||
@@ -305,114 +283,108 @@ const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
|
||||
```typescript
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: search,
|
||||
pageList: fetchList,
|
||||
onLoaded: async (state) => {
|
||||
// 字典数据转换
|
||||
state.dataList = convertDictData(state.dataList)
|
||||
|
||||
// 处理 auditAll 等逻辑
|
||||
// 注意:需要在 API 响应中获取,或通过其他方式处理
|
||||
}
|
||||
})
|
||||
queryForm: search,
|
||||
pageList: fetchList,
|
||||
onLoaded: async (state) => {
|
||||
// 字典数据转换
|
||||
state.dataList = convertDictData(state.dataList);
|
||||
|
||||
// 处理 auditAll 等逻辑
|
||||
// 注意:需要在 API 响应中获取,或通过其他方式处理
|
||||
},
|
||||
});
|
||||
```
|
||||
|
||||
## 完整改造示例(针对当前页面)
|
||||
|
||||
```typescript
|
||||
// 1. 导入 useTable
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table'
|
||||
import { BasicTableProps, useTable } from '/@/hooks/table';
|
||||
|
||||
// 2. 搜索表单数据(保持不变)
|
||||
const search = reactive({
|
||||
deptCode: '',
|
||||
secDeptCode: '',
|
||||
tied: '',
|
||||
realName: '',
|
||||
teacherNo: '',
|
||||
retireDate: '',
|
||||
pfTitleId: '',
|
||||
stationDutyLevelId: '',
|
||||
politicsStatus: '',
|
||||
teacherCate: '',
|
||||
inoutFlag: ''
|
||||
})
|
||||
deptCode: '',
|
||||
secDeptCode: '',
|
||||
tied: '',
|
||||
realName: '',
|
||||
teacherNo: '',
|
||||
retireDate: '',
|
||||
pfTitleId: '',
|
||||
stationDutyLevelId: '',
|
||||
politicsStatus: '',
|
||||
teacherCate: '',
|
||||
inoutFlag: '',
|
||||
});
|
||||
|
||||
// 3. 额外参数(用于 flag 等)
|
||||
const params = ref<any>({})
|
||||
const params = ref<any>({});
|
||||
|
||||
// 4. 配置 useTable
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: search, // 将 search 作为 queryForm
|
||||
|
||||
// 自定义 pageList,合并额外参数
|
||||
pageList: async (queryParams: any) => {
|
||||
// 合并 search 和 params
|
||||
const mergedParams = {
|
||||
...queryParams,
|
||||
...params.value,
|
||||
tied: search.tied // 如果需要特殊处理
|
||||
}
|
||||
return await fetchList(mergedParams)
|
||||
},
|
||||
|
||||
// 数据属性映射
|
||||
props: {
|
||||
item: 'record.records',
|
||||
totalCount: 'record.total'
|
||||
},
|
||||
|
||||
// 数据加载完成回调
|
||||
onLoaded: async (state) => {
|
||||
// 字典数据转换
|
||||
state.dataList = convertDictData(state.dataList)
|
||||
|
||||
// 注意:auditAll 需要从 API 响应中获取
|
||||
// 如果 API 返回在 response.data.auditAll,需要特殊处理
|
||||
}
|
||||
})
|
||||
queryForm: search, // 将 search 作为 queryForm
|
||||
|
||||
// 自定义 pageList,合并额外参数
|
||||
pageList: async (queryParams: any) => {
|
||||
// 合并 search 和 params
|
||||
const mergedParams = {
|
||||
...queryParams,
|
||||
...params.value,
|
||||
tied: search.tied, // 如果需要特殊处理
|
||||
};
|
||||
return await fetchList(mergedParams);
|
||||
},
|
||||
|
||||
// 数据属性映射
|
||||
props: {
|
||||
item: 'record.records',
|
||||
totalCount: 'record.total',
|
||||
},
|
||||
|
||||
// 数据加载完成回调
|
||||
onLoaded: async (state) => {
|
||||
// 字典数据转换
|
||||
state.dataList = convertDictData(state.dataList);
|
||||
|
||||
// 注意:auditAll 需要从 API 响应中获取
|
||||
// 如果 API 返回在 response.data.auditAll,需要特殊处理
|
||||
},
|
||||
});
|
||||
|
||||
// 5. 使用 useTable
|
||||
const {
|
||||
getDataList,
|
||||
currentChangeHandle,
|
||||
sizeChangeHandle,
|
||||
tableStyle,
|
||||
state
|
||||
} = useTable(state)
|
||||
const { getDataList, currentChangeHandle, sizeChangeHandle, tableStyle, state } = useTable(state);
|
||||
|
||||
// 6. 查询方法(简化)
|
||||
const handleFilter = (param: any) => {
|
||||
params.value = { ...param }
|
||||
getDataList() // 自动跳转到第一页
|
||||
}
|
||||
params.value = { ...param };
|
||||
getDataList(); // 自动跳转到第一页
|
||||
};
|
||||
|
||||
// 7. 重置查询
|
||||
const resetQuery = () => {
|
||||
searchFormRef.value?.formRef?.resetFields()
|
||||
Object.keys(search).forEach(key => {
|
||||
search[key] = ''
|
||||
})
|
||||
params.value = {}
|
||||
getDataList()
|
||||
}
|
||||
searchFormRef.value?.formRef?.resetFields();
|
||||
Object.keys(search).forEach((key) => {
|
||||
search[key] = '';
|
||||
});
|
||||
params.value = {};
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 8. 快速查询
|
||||
const handelQuickSeach = (val: any) => {
|
||||
params.value.flag = val
|
||||
getDataList()
|
||||
}
|
||||
params.value.flag = val;
|
||||
getDataList();
|
||||
};
|
||||
|
||||
// 9. 其他需要刷新的地方
|
||||
const updateInoutFlag = (row: any, val: any) => {
|
||||
const updateParams = {"teacherNo": row.teacherNo, "inoutFlag": val}
|
||||
messageBox.confirm('确认操作?').then(() => {
|
||||
updateInout(updateParams).then((res: any) => {
|
||||
message.success("修改成功")
|
||||
getDataList(false) // 保持当前页
|
||||
})
|
||||
})
|
||||
}
|
||||
const updateParams = { teacherNo: row.teacherNo, inoutFlag: val };
|
||||
messageBox.confirm('确认操作?').then(() => {
|
||||
updateInout(updateParams).then((res: any) => {
|
||||
message.success('修改成功');
|
||||
getDataList(false); // 保持当前页
|
||||
});
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
@@ -434,12 +406,12 @@ props: {
|
||||
|
||||
```typescript
|
||||
pageList: async (queryParams: any) => {
|
||||
return await fetchList({
|
||||
...queryParams,
|
||||
...params.value, // 额外参数
|
||||
// 或其他特殊参数
|
||||
})
|
||||
}
|
||||
return await fetchList({
|
||||
...queryParams,
|
||||
...params.value, // 额外参数
|
||||
// 或其他特殊参数
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
### 3. 数据转换
|
||||
@@ -448,8 +420,8 @@ pageList: async (queryParams: any) => {
|
||||
|
||||
```typescript
|
||||
onLoaded: async (state) => {
|
||||
state.dataList = convertDictData(state.dataList)
|
||||
}
|
||||
state.dataList = convertDictData(state.dataList);
|
||||
};
|
||||
```
|
||||
|
||||
### 4. 特殊响应字段
|
||||
@@ -458,20 +430,20 @@ onLoaded: async (state) => {
|
||||
|
||||
```typescript
|
||||
pageList: async (queryParams: any) => {
|
||||
const response = await fetchList({
|
||||
...queryParams,
|
||||
...params.value
|
||||
})
|
||||
|
||||
// 处理特殊字段
|
||||
if (response.data.auditAll == '0') {
|
||||
auditAll.value = false
|
||||
} else {
|
||||
auditAll.value = true
|
||||
}
|
||||
|
||||
return response
|
||||
}
|
||||
const response = await fetchList({
|
||||
...queryParams,
|
||||
...params.value,
|
||||
});
|
||||
|
||||
// 处理特殊字段
|
||||
if (response.data.auditAll == '0') {
|
||||
auditAll.value = false;
|
||||
} else {
|
||||
auditAll.value = true;
|
||||
}
|
||||
|
||||
return response;
|
||||
};
|
||||
```
|
||||
|
||||
### 5. 初始化数据加载
|
||||
@@ -480,17 +452,17 @@ pageList: async (queryParams: any) => {
|
||||
|
||||
```typescript
|
||||
const state: BasicTableProps = reactive<BasicTableProps>({
|
||||
queryForm: search,
|
||||
pageList: fetchList,
|
||||
createdIsNeed: false // 禁用自动加载
|
||||
})
|
||||
queryForm: search,
|
||||
pageList: fetchList,
|
||||
createdIsNeed: false, // 禁用自动加载
|
||||
});
|
||||
|
||||
// 手动调用
|
||||
onMounted(() => {
|
||||
init()
|
||||
loadSearchDictData()
|
||||
getDataList() // 手动加载
|
||||
})
|
||||
init();
|
||||
loadSearchDictData();
|
||||
getDataList(); // 手动加载
|
||||
});
|
||||
```
|
||||
|
||||
## 优势总结
|
||||
@@ -513,4 +485,3 @@ onMounted(() => {
|
||||
4. 使用 `currentChangeHandle`、`sizeChangeHandle` 替代手动分页方法
|
||||
|
||||
如果有额外参数或特殊处理,使用自定义 `pageList` 方法或 `onLoaded` 回调即可。
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
**所有按钮统一使用默认尺寸**,不需要设置 `size` 属性。
|
||||
|
||||
- 高度:32px(Element Plus默认)
|
||||
- 高度:32px(Element Plus 默认)
|
||||
- 适用于所有场景:页面操作区域、表格操作列、对话框底部等
|
||||
|
||||
```vue
|
||||
@@ -16,21 +16,22 @@
|
||||
|
||||
## 二、颜色
|
||||
|
||||
| 操作类型 | type | plain | 颜色 | 使用场景 |
|
||||
|---------|------|-------|------|---------|
|
||||
| 主要操作 | `primary` | - | 蓝色实心 | 新增、保存、提交 |
|
||||
| 查询 | `primary` | - | 蓝色实心 | 查询 |
|
||||
| 重置 | - | - | 灰色 | 重置 |
|
||||
| 导出操作 | `warning` | ✓ | 橙色边框 | 导出、下载 |
|
||||
| 导入操作 | `primary` | ✓ | 蓝色边框 | 导入、上传 |
|
||||
| 设置操作 | `primary` | ✓ | 蓝色边框 | 设置、配置 |
|
||||
| 同步操作 | `primary` | ✓ | 蓝色边框 | 同步、连接 |
|
||||
| 状态锁定 | - | - | 灰色 | 状态锁定、解锁 |
|
||||
| 危险操作 | `danger` | - | 红色实心 | 删除、清空 |
|
||||
| 操作类型 | type | plain | 颜色 | 使用场景 |
|
||||
| -------- | --------- | ----- | -------- | ---------------- |
|
||||
| 主要操作 | `primary` | - | 蓝色实心 | 新增、保存、提交 |
|
||||
| 查询 | `primary` | - | 蓝色实心 | 查询 |
|
||||
| 重置 | - | - | 灰色 | 重置 |
|
||||
| 导出操作 | `warning` | ✓ | 橙色边框 | 导出、下载 |
|
||||
| 导入操作 | `primary` | ✓ | 蓝色边框 | 导入、上传 |
|
||||
| 设置操作 | `primary` | ✓ | 蓝色边框 | 设置、配置 |
|
||||
| 同步操作 | `primary` | ✓ | 蓝色边框 | 同步、连接 |
|
||||
| 状态锁定 | - | - | 灰色 | 状态锁定、解锁 |
|
||||
| 危险操作 | `danger` | - | 红色实心 | 删除、清空 |
|
||||
|
||||
## 三、样式
|
||||
|
||||
### 1. 实心按钮(默认)
|
||||
|
||||
- **使用场景**:新增、保存、删除等主要操作
|
||||
- **代码**:`type="primary"` 或 `type="danger"`
|
||||
|
||||
@@ -39,7 +40,8 @@
|
||||
<el-button type="danger" icon="Delete">删 除</el-button>
|
||||
```
|
||||
|
||||
### 2. Plain按钮(边框样式)
|
||||
### 2. Plain 按钮(边框样式)
|
||||
|
||||
- **使用场景**:重置、导出、导入、设置、同步等次要操作
|
||||
- **代码**:`type="primary" plain` 或 `type="warning" plain`
|
||||
|
||||
@@ -52,6 +54,7 @@
|
||||
```
|
||||
|
||||
### 3. 设置按钮
|
||||
|
||||
- **使用场景**:设置、配置等操作
|
||||
- **代码**:`type="primary" plain`
|
||||
|
||||
@@ -60,6 +63,7 @@
|
||||
```
|
||||
|
||||
### 4. 同步按钮
|
||||
|
||||
- **使用场景**:同步、连接等操作
|
||||
- **代码**:`type="primary" plain`
|
||||
|
||||
@@ -68,6 +72,7 @@
|
||||
```
|
||||
|
||||
### 5. 默认按钮(灰色)
|
||||
|
||||
- **使用场景**:状态锁定、解锁等中性操作
|
||||
- **代码**:不设置 `type` 属性
|
||||
|
||||
@@ -76,6 +81,7 @@
|
||||
```
|
||||
|
||||
### 6. 表格操作列按钮(link)
|
||||
|
||||
- **使用场景**:表格操作列,使用 `link` 属性
|
||||
- **代码**:`link` 属性,配合 `type` 使用
|
||||
- **说明**:表格内的操作按钮统一使用 `link` 样式,节省空间
|
||||
@@ -93,25 +99,25 @@
|
||||
|
||||
### 常用图标映射
|
||||
|
||||
| 操作类型 | 图标名称 |
|
||||
|---------|---------|
|
||||
| 查询 | `Search` |
|
||||
| 重置 | `Refresh` |
|
||||
| 新增/添加 | `FolderAdd` |
|
||||
| 导出/下载 | `Download` |
|
||||
| 导入/上传 | `UploadFilled` |
|
||||
| 编辑/修改 | `EditPen` |
|
||||
| 删除 | `Delete` |
|
||||
| 批量删除 | `DocumentDelete` |
|
||||
| 通过 | `CircleCheck` |
|
||||
| 驳回 | `CircleClose` |
|
||||
| 查看图片 | `Picture` |
|
||||
| 详情/其他 | `Document` |
|
||||
| 设置/配置 | `Setting` |
|
||||
| 锁定/解锁 | `Lock` |
|
||||
| 用户相关 | `User` |
|
||||
| 调动/转换 | `Switch` |
|
||||
| 同步/连接 | `Connection` |
|
||||
| 操作类型 | 图标名称 |
|
||||
| --------- | ---------------- |
|
||||
| 查询 | `Search` |
|
||||
| 重置 | `Refresh` |
|
||||
| 新增/添加 | `FolderAdd` |
|
||||
| 导出/下载 | `Download` |
|
||||
| 导入/上传 | `UploadFilled` |
|
||||
| 编辑/修改 | `EditPen` |
|
||||
| 删除 | `Delete` |
|
||||
| 批量删除 | `DocumentDelete` |
|
||||
| 通过 | `CircleCheck` |
|
||||
| 驳回 | `CircleClose` |
|
||||
| 查看图片 | `Picture` |
|
||||
| 详情/其他 | `Document` |
|
||||
| 设置/配置 | `Setting` |
|
||||
| 锁定/解锁 | `Lock` |
|
||||
| 用户相关 | `User` |
|
||||
| 调动/转换 | `Switch` |
|
||||
| 同步/连接 | `Connection` |
|
||||
|
||||
### 使用示例
|
||||
|
||||
@@ -126,7 +132,7 @@
|
||||
|
||||
## 五、间距
|
||||
|
||||
按钮之间使用 `class="ml10"` 保持10px的左边距,确保按钮组视觉统一。
|
||||
按钮之间使用 `class="ml10"` 保持 10px 的左边距,确保按钮组视觉统一。
|
||||
|
||||
```vue
|
||||
<el-button type="primary" icon="FolderAdd">新 增</el-button>
|
||||
@@ -229,15 +235,15 @@
|
||||
|
||||
## 七、快速参考
|
||||
|
||||
| 要素 | 规范 |
|
||||
|------|------|
|
||||
| **尺寸** | 统一使用默认尺寸,不设置 `size` 属性 |
|
||||
| **颜色** | 主要操作用蓝色实心,次要操作用蓝色/橙色边框,危险操作用红色 |
|
||||
| 要素 | 规范 |
|
||||
| -------- | --------------------------------------------------------------- |
|
||||
| **尺寸** | 统一使用默认尺寸,不设置 `size` 属性 |
|
||||
| **颜色** | 主要操作用蓝色实心,次要操作用蓝色/橙色边框,危险操作用红色 |
|
||||
| **样式** | 主要操作用实心,次要操作用 `plain`,**表格操作列必须用 `link`** |
|
||||
| **图标** | 所有按钮必须配合图标,使用 PascalCase 格式 |
|
||||
| **间距** | 按钮之间使用 `class="ml10"` 保持10px间距 |
|
||||
| **图标** | 所有按钮必须配合图标,使用 PascalCase 格式 |
|
||||
| **间距** | 按钮之间使用 `class="ml10"` 保持 10px 间距 |
|
||||
|
||||
---
|
||||
|
||||
**维护者:** 前端开发团队
|
||||
**最后更新:** 2024年
|
||||
**最后更新:** 2024 年
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
198383
docs/默认模块.openapi.json
198383
docs/默认模块.openapi.json
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user