Vue3 组合式 API 来封装表格数据请求

2023-07-1908:17:24WEB前端开发Comments1,045 views字数 3200阅读模式

阅读 aHooks 文档时发现了一个非常实用的函数 useAntdTable,它封装了一些 Ant Design FormAnt Design Table 常见的逻辑。刚好最近我自己也封装了一个类似的 Table 组件 x-table,它是基于 el-table 实现的。因此,也想尝试封装一个类似的函数,来简化一些常见业务功能的开发。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html

与 React 的 Hook 类似,Vue3 提供了组合式 API 来帮助我们封装和复用有状态逻辑。下面我将介绍如何使用 Vue3 的组合式函数来实现一个简单而强大的 useTable 函数。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html

使用

首先,让我们看一下 useTable 函数是如何使用的:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html

基础用法

<template>
  <x-table :columns="columns" v-bind="tableProps" >
</template>

<script setup lang='ts'>
  const { tableProps } = useTable(getArticleList)
</script>

简单吗?只要几行代码就能轻松搞定一个报表页面,剩下的时间我们是不是就可以用来愉快的)了。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html

高级用法

除了基本用法,useTable 函数还提供了其他配置项,以便应对不同的需求。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html

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 函数接受两个参数:serviceoptionsservice 用于获取数据的函数,而 options 则是一些配置项。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html

Vue3 组合式 API 来封装表格数据请求文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html

通过使用泛型参数,我们可以根据传入的 getArticleList 方法来推断出具体的参数和返回值类型。这也是令我最满意的地方。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html

配置项

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;
}

函数返回一个包含以下属性的对象:文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html

  • 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 使用,提供表格需要的一些属性。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html

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 函数中,我们根据配置项的设置来发起数据请求,并根据返回结果更新相应的数据。同时,在请求过程中,我们可以调用成功、失败和结束时的回调函数,以便处理额外的逻辑。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html

完整的代码和 Demo 可以在我的 GitHub 仓库 Ares-admin 中查看。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html

总结

通过 useTable 函数,我们可以轻松实现一些常见的业务功能,提高代码的可维护性和复用性,节省开发时间。需要注意的是,由于本文中 useTable 没有在项目中实践,可能有一些不完善的地方,仅供参考学习。文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html

作者:zhangsanplus
来源:稀土掘金文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html
文章源自菜鸟学院-https://www.cainiaoxueyuan.com/gcs/51826.html
  • 本站内容整理自互联网,仅提供信息存储空间服务,以方便学习之用。如对文章、图片、字体等版权有疑问,请在下方留言,管理员看到后,将第一时间进行处理。
  • 转载请务必保留本文链接:https://www.cainiaoxueyuan.com/gcs/51826.html

Comment

匿名网友 填写信息

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定