自定义hooks
在 vue2 里面有一些公共的逻辑,我们可以使用 mixins(混入)。vue3 里面的逻辑复用,官方推荐的方式包括自定义组合式函数,也就是自定义一些hooks,官方案例。
vue官方也有一些好用的 hooks 工具集,vueuse 其中的一些 hook 在 nuxt3 里面也是开箱即用,例如 useFetch。
useFetch 可以发送一个 fetch 请求,并且返回响应式的数据。简化我们创建响应式数据并且请求赋值的流程,非常的方便。
自定义一个 useFetch
通常我们的前端项目都使用 axios 来封装发送请求,但是 useFetch 里面发送请求的却是其他的库 ofetch,具体可以查看 nuxt3 里面 useFetch 的说明。
所以我就封装了一个基于自己的项目的 useFetch 处理请求的方法。代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| import {ref, watch} from 'vue'; import {ElMessage} from "element-plus";
export const useFetch = (fetch, { immediate = true, // 是否立即发送请求 effectArray = [], // 副作用依赖项,watch 监听,以便重新发送请求 beforeFetch, // 请求发送之前执行的回调 afterFetch, // 请求发送之后执行的回调 onSuccess, // 成功的回调函数 onError, // 错误的回调函数 updateDataOnError = false, // 接口出错时是否更新数据 initialData = null // 初始化数据响应式数据,可用于页面渲染 } = { immediate: true, updateDataOnError: false, effectArray: [], initialData: null }) => {
const isLoading = ref(false) const isFinished = ref(false) const data = ref(initialData) const response = ref(null) const error = ref(null)
const execute = () => { beforeFetch && beforeFetch() isLoading.value = true isFinished.value = false error.value = null fetch().then(res => { response.value = res if (res?.status === '00000') { onSuccess && onSuccess(res) data.value = res.data } else { ElMessage.error(res?.message) if (updateDataOnError) { data.value = null } } }).catch(e => { onError && onError(e) error.value = e }).finally(() => { afterFetch && afterFetch() isLoading.value = false isFinished.value = true }) }
if (immediate) { execute() }
const debounceExecute = debounce(execute, 100)
if (effectArray.length > 0) { watch(effectArray, debounceExecute) }
return { isLoading, isFinished, response, error, data, execute } }
|
使用案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const page = reactive({ pageNum: 1, pageSize: 10 })
const initialData = reactive({ list: [], total: 0 })
const {data} = useFetch(() => axios.post('/getList',{pageNum: page.pageNum,pageSize: page.pageSize}), { initialData, immediate: false, effectArray: [() => page.pageNum,() => page.pageSize] })
|
大家可以根据自己的项目需求修改一些配置。 类似的也可以根据 react 里面 useState, useEffect 创建一个 react 版本的 useFetch。ahooks 也是不错的导师,里面可以学到很多思路。