12 KiB
12 KiB
useTable 与 search-form 组件兼容使用说明
概述
useTable Hook 完全兼容自定义 <search-form> 组件。只需要将搜索表单的数据对象作为 queryForm 传入即可。
兼容原理
search-form组件:只是一个表单包装器,接收modelprop 绑定到内部的el-formuseTableHook:接收queryForm对象,会自动将其合并到 API 请求参数中- 两者配合:将
search-form的model对象作为useTable的queryForm传入即可
改造示例
当前代码(手动管理)
<template>
<!-- 搜索表单 -->
<search-form
v-show="showSearch"
:model="search"
ref="searchFormRef"
@keyup-enter="handleFilter(search)"
>
<!-- 表单项 -->
</search-form>
<!-- 表格 -->
<el-table :data="tableData" v-loading="tableLoading">
<!-- 表格列 -->
</el-table>
<!-- 分页 -->
<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: '',
// ... 其他字段
})
const tableData = ref([])
const tableLoading = ref(false)
const page = reactive({
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
})
}
// 手动实现分页
const currentChange = (val: number) => {
page.currentPage = val
getList(page)
}
const handleSizeChange = (val: number) => {
page.pageSize = val
page.currentPage = 1
getList(page)
}
// 查询
const handleFilter = (param: any) => {
params.value = { ...param }
page.currentPage = 1
getList(page)
}
onMounted(() => {
getList(page)
})
</script>
改造后代码(使用 useTable)
<template>
<!-- 搜索表单 - 保持不变 -->
<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.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'
// 搜索表单数据 - 保持不变
const search = reactive({
deptCode: '',
realName: '',
teacherNo: '',
// ... 其他字段
})
// 额外参数(如 flag 等)
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)
// ...
}
})
// 使用 useTable Hook
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
tableStyle,
state
} = useTable(state)
// 查询方法 - 简化
const handleFilter = (param: any) => {
// 更新额外参数
params.value = { ...param }
// 调用 getDataList 刷新数据(会自动跳转到第一页)
getDataList()
}
// 重置查询
const resetQuery = () => {
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)
}
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 convertDictData = (records: any[]) => {
// ... 转换逻辑
return records
}
</script>
关键改造点
1. 导入 useTable
import { BasicTableProps, useTable } from '/@/hooks/table'
2. 配置 state
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: search, // 将 search 对象作为 queryForm
pageList: fetchList, // 或自定义方法
props: {
item: 'record.records',
totalCount: 'record.total'
}
})
3. 处理额外参数
如果查询时需要额外的参数(如 params.value.flag),有两种方式:
方式一:自定义 pageList 方法(推荐)
const params = ref<any>({})
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: search,
pageList: async (queryParams: any) => {
// 合并额外参数
return await fetchList({
...queryParams,
...params.value // 合并额外参数
})
}
})
方式二:在 onLoaded 中处理
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: search,
pageList: fetchList,
onLoaded: async (state) => {
// 可以在这里处理数据转换等逻辑
}
})
4. 替换数据引用
| 原代码 | 改造后 |
|---|---|
tableData |
state.dataList |
tableLoading |
state.loading |
page.currentPage |
state.pagination.current |
page.pageSize |
state.pagination.size |
page.total |
state.pagination.total |
5. 替换方法调用
| 原代码 | 改造后 |
|---|---|
getList(page) |
getDataList() 或 getDataList(false) |
currentChange(val) |
currentChangeHandle(val) |
handleSizeChange(val) |
sizeChangeHandle(val) |
6. 处理数据转换
如果需要在数据加载后进行转换,使用 onLoaded 回调:
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: search,
pageList: fetchList,
onLoaded: async (state) => {
// 字典数据转换
state.dataList = convertDictData(state.dataList)
// 处理 auditAll 等逻辑
// 注意:需要在 API 响应中获取,或通过其他方式处理
}
})
完整改造示例(针对当前页面)
// 1. 导入 useTable
import { BasicTableProps, useTable } from '/@/hooks/table'
// 2. 搜索表单数据(保持不变)
const search = reactive({
deptCode: '',
secDeptCode: '',
tied: '',
realName: '',
teacherNo: '',
retireDate: '',
pfTitleId: '',
stationDutyLevelId: '',
politicsStatus: '',
teacherCate: '',
inoutFlag: ''
})
// 3. 额外参数(用于 flag 等)
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,需要特殊处理
}
})
// 5. 使用 useTable
const {
getDataList,
currentChangeHandle,
sizeChangeHandle,
tableStyle,
state
} = useTable(state)
// 6. 查询方法(简化)
const handleFilter = (param: any) => {
params.value = { ...param }
getDataList() // 自动跳转到第一页
}
// 7. 重置查询
const resetQuery = () => {
searchFormRef.value?.formRef?.resetFields()
Object.keys(search).forEach(key => {
search[key] = ''
})
params.value = {}
getDataList()
}
// 8. 快速查询
const handelQuickSeach = (val: any) => {
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) // 保持当前页
})
})
}
注意事项
1. API 响应结构
如果 API 返回结构是 response.data.record.records,需要配置 props:
props: {
item: 'record.records',
totalCount: 'record.total'
}
2. 额外参数处理
如果查询时需要额外的参数(不在 search 对象中),使用自定义 pageList 方法合并:
pageList: async (queryParams: any) => {
return await fetchList({
...queryParams,
...params.value, // 额外参数
// 或其他特殊参数
})
}
3. 数据转换
如果需要在数据加载后进行转换,使用 onLoaded 回调:
onLoaded: async (state) => {
state.dataList = convertDictData(state.dataList)
}
4. 特殊响应字段
如果 API 响应中有特殊字段(如 auditAll),需要在 onLoaded 中处理,或者自定义 pageList 方法:
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
}
5. 初始化数据加载
useTable 默认会在 onMounted 时自动加载数据。如果不需要自动加载,设置:
const state: BasicTableProps = reactive<BasicTableProps>({
queryForm: search,
pageList: fetchList,
createdIsNeed: false // 禁用自动加载
})
// 手动调用
onMounted(() => {
init()
loadSearchDictData()
getDataList() // 手动加载
})
优势总结
使用 useTable 后:
- ✅ 代码量减少:不需要手动管理
tableData、tableLoading、page - ✅ 自动状态管理:loading、分页、数据自动管理
- ✅ 统一方法:
getDataList()统一刷新数据 - ✅ 兼容性好:完全兼容自定义
search-form组件 - ✅ 灵活扩展:支持自定义
pageList、onLoaded等回调
总结
useTable 完全兼容自定义 <search-form> 组件,只需要:
- 将
search对象作为queryForm传入 - 使用
state.dataList、state.loading、state.pagination替代手动管理的状态 - 使用
getDataList()替代getList(page) - 使用
currentChangeHandle、sizeChangeHandle替代手动分页方法
如果有额外参数或特殊处理,使用自定义 pageList 方法或 onLoaded 回调即可。