使用 Vue3 组合式 API 来封装表格数据请求
前段时间我在阅读 aHooks
文档时发现了一个非常实用的函数 useAntdTable
,它封装了一些 Ant Design Form
和 Ant Design Table
常见的逻辑。刚好最近我自己也封装了一个类似的 Table 组件 x-table,它是基于 el-table
实现的。因此,也想尝试封装一个类似的函数,来简化一些常见业务功能的开发。
与 React 的 Hook 类似,Vue3 提供了组合式 API 来帮助我们封装和复用有状态逻辑。下面我将介绍如何使用 Vue3 的组合式函数来实现一个简单而强大的 useTable
函数。
使用
首先,让我们看一下 useTable
函数是如何使用的:
基础用法
<template>
<x-table :columns="columns" v-bind="tableProps" >
</template>
<script setup lang='ts'>
const { tableProps } = useTable(getArticleList)
</script>
简单吗?只要几行代码就能轻松搞定一个报表页面,剩下的时间我们是不是就可以用来愉快的学(摸)习(鱼)了。
高级用法
除了基本用法,useTable
函数还提供了其他配置项,以便应对不同的需求。
const options = {
immediate: true, // 默认立即加载数据
pageable: true, // 是否可分页,默认为true
defaultParams: { keyword: "" }, // 默认的查询参数
defaultSort: { prop: "age", order: "ascending" }, // 默认的排序参数
defaultPaging: { pageNum: 1, pageSize: 10 }, // 默认的分页参数
onSuccess: (data, params) => {
console.log("请求成功:", data);
},
onError: (error, params) => {
console.error("请求失败:", error);
},
onFinally: () => {
console.log("请求结束");
},
};
const { loading, form, data, total, tableProps, query, reset } = useTable(
service,
options
);
设计与实现
类型定义
function useTable<TDataItem, TParams extends Record<string, any>>(
service: UseTableService<PagingResult<TDataItem[]> | TDataItem[], TParams>,
options: UseTableOptions<PagingResult<TDataItem[]> | TDataItem[], TParams>
): UseTableReturn<TDataItem, TParams>;
useTable
函数接受两个参数:service
和 options
。service
用于获取数据的函数,而 options
则是一些配置项。
通过使用泛型参数,我们可以根据传入的 getArticleList
方法来推断出具体的参数和返回值类型。这也是令我最满意的地方。
配置项
interface UseTableOptions<TResult, TParams> {
immediate?: boolean;
pageable?: boolean;
defaultParams?: TParams;
defaultSort?: TableSort;
defaultPaging?: Partial<TablePaging>;
onSuccess?: (
data: HttpResponse<TResult>,
params: Record<string, any>
) => void;
onError?: (e: unknown, params: Record<string, any>) => void;
onFinally?: () => void;
}
immediate
: 是否立即加载数据pageable
: 是否需要分页defaultParams
: 查询表单默认数据defaultSort
: 默认的排序规则defaultPaging
: 默认的分页规则onSuccess
: 请求成功时的回调onError
: 请求失败时的回调onFinally
: 请求结束时的回调
返回值
interface UseTableReturn<TDataItem, TParams> {
tableProps: ComputedRef<TableProps<TDataItem>>;
loading: Ref<boolean>;
form: Ref<TParams>;
data: ShallowRef<TDataItem[]>;
query: () => Promise<void>;
reset: () => Promise<void>;
cancel: () => void;
}
函数返回一个包含以下属性的对象:
tableProps
:表格的属性,包括表格数据、分页排序等loading
: 接口请求状态form
: 响应式表单数据data
: 接口返回的表格数据query
获取数据的函数reset
重置表格参数,并重新获取数据cancel
取消请求的函数
代码实现
const tableProps = computed<TableProps<TDataItem>>(() => {
const { defaultSort } = options
const { pageSize, pageNum } = pagingData.value
return {
loading: loading.value,
dataSource: data.value,
total: total.value,
pageable,
pageSize,
pageNum,
defaultSort,
onChange,
}
})
tableProps 主要是配合 x-table 使用,提供表格需要的一些属性。
const fetchData = async () => {
if (loading.value) return;
loading.value = true;
const params = getParams();
try {
controller.value = new AbortController();
const res = await service(params, {
signal: controller.value.signal,
});
if (pageable) {
const ret = res.data as PagingResult<TDataItem[]>;
data.value = ret.list;
total.value = ret.count;
} else {
const ret = res.data as TDataItem[];
data.value = ret;
}
onSuccess?.(res, params);
} catch (error) {
onError?.(error, params);
} finally {
loading.value = false;
onFinally?.();
}
};
在 fetchData
函数中,我们根据配置项的设置来发起数据请求,并根据返回结果更新相应的数据。同时,在请求过程中,我们可以调用成功、失败和结束时的回调函数,以便处理额外的逻辑。
完整的代码和 Demo 可以在我的 GitHub 仓库 Ares-admin 中查看。
总结
通过 useTable
函数,我们可以轻松实现一些常见的业务功能,提高代码的可维护性和复用性,节省开发时间。需要注意的是,由于本文中 useTable
没有在项目中实践,可能有一些不完善的地方,仅供参考学习。
最后,欢迎大家在评论区讨论学习,分享自己的经验和更好的想法。
转载自:https://juejin.cn/post/7256730001805754427