Vue3 开发秘籍,封装一个超级好用的 Hook

高级前端进阶

共 4930字,需浏览 10分钟

 ·

2024-04-15 09:10

关注我,回复“加群

加入我们一起学习,天天进步


Vue3 的 Composition API 为我们提供了另一种代码组织方式,这个概念借鉴自 React 的 Hook。在 16.8 的版本中,React 引入了 React Hook,通过封装有状态的函数,提高了组件的编写效率和可维护性,在后面统一使用 Hook 来替代“组合式函数”。

Hook 允许我们将逻辑封装为可复用的函数,这些函数可以让你在组件之外管理状态和逻辑,从而在多个组件之间共享和复用。

封装自己的 Vue Hook

下面我们通过一个实际的业务场景来学习如何封装自己的 Vue Hook。我们将创建一个 useTable Hook,它用于从 API 获取表格数据并支持分页。

基础版 useTable Hook

首先,我们定义一个简单的 useTable Hook,它通过调用 API 返回表格数据,并支持刷新。

// useTable.js
import { ref } from 'vue';
export function useTable(api{
  const data = ref([]);
  const refresh = () => {
    api().then(res => data.value = res);
  };
  refresh();
  return [data, refresh];
}

支持分页查询

为了使 useTable 支持分页查询,我们需要对 API 进行改造,使其能够接受分页参数并返回分页数据。

// api.ts
export const getTableDataApi = (page, limit) => {
  // ... 接口返回分页数据
}

然后,我们更新 useTable Hook 以处理分页逻辑。

// const sizeOption = [10, 20, 50, 100, 200];
// useTable.js
import { reactive } from 'vue';
export function useTable(api, options{
  const pagination = reactive({
    current1,
    total0,
    sizeOption,
    size: sizeOption[0],
    // ... 分页方法
  });
  // ... 刷新数据的逻辑
  return [pagination, refresh];
}

处理 API 参数和加载状态

为了使 useTable 更加灵活,我们可以让 API 接受参数,并添加加载状态的管理。

// useTable.js
import { get } from "lodash-es";

export function useTable(api, options) {
  const { path = {}, immediate = false } = options || {};
  const { data: dataPath, total: totalPath, page: pagePath, size: sizePath } = path;
  const [pagination, setPagination] = useState({
    current1,
    size10,
    total0,
  });
  const [loading, setLoading] = useState(false);
  const data = ref([]);

  const refresh = async () => {
    setLoading(true);
    const { current, size } = pagination;
    const res = await api({ [pagePath]: current, [sizePath]: size });
    data.value = get(res, dataPath) || [];
    setPagination(prevState => ({ ...prevState, totalget(res, totalPath) || 0 }));
    setLoading(false);
  };

  useEffect(() => {
    if (immediate) {
      refresh();
    }
  }, [immediate]);

  return { data, pagination, refresh, loading };
}

在这个版本中,useTable Hook 接受一个 API 函数和一个选项对象,其中选项对象可以包含路径信息和是否立即刷新数据的标志。我们还添加了 loading 状态。

使用 useTable Hook

在组件中,我们可以通过 useTable Hook 的返回值来控制分页和数据加载。

<script setup>
import { useTable } from './useTable.js';
import { getTableDataApi } from './api.ts';

const { data, pagination, refresh, loading } = useTable(getTableDataApi, {
  path: {
    data'items',
    total'totalCount',
    page'currentPage',
    size'pageSize'
  },
  immediatetrue
});
</script>

<template>
  <el-table :data="data" style="width: 100%">
    <!-- 列定义 -->
  </el-table>
  <el-pagination
    v-model:current-page="pagination.current"
    :page-size="pagination.size"
    :total="pagination.total"
  >
</el-pagination>
  <button @click="refresh">Refresh</button>
  <div v-if="loading">Loading...</div>
</template>

在这个例子中,我们使用 Element Plus 的表格和分页组件来展示 useTable Hook 的功能。我们可以通过分页组件来改变当前页和每页大小,并使用 refresh 函数来手动刷新数据。

总结

我们学习了如何封装一个功能完善的 useTable Hook,它不仅支持分页查询,还能够处理 API 参数和加载状态。这样的封装使得我们的代码可维护更高,同时也提高了开发效率。


最后不要忘了点赞和在看呦!

祝 2024 年暴富!暴美!暴瘦!

浏览 134
10点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
10点赞
评论
收藏
分享

手机扫一扫分享

分享
举报