UNPKG

@ithinkdt/core

Version:

iThinkDT Core

95 lines (91 loc) 3.14 kB
import { inject, ref, shallowRef } from 'vue' import { request, HttpError } from '@ithinkdt/common' import { $FETCH } from './plugin' export function useFetch(api, options = {}) { let fn, options2 = {} if (!api) { api = 'get: ' } if (typeof api === 'function') { fn = api } else { const $fetch = options?.$fetch ?? inject($FETCH, request) let _api if (typeof api === 'string') { const index = api.indexOf(':') const [method, reqType] = api.slice(0, Math.max(0, index)).split('|') _api = { url: api.slice(Math.max(0, index + 1)), method, reqType, } } else { _api = api } options.method = _api.method ?? options?.method const { url, method = options.method ?? 'get', before, after, shallow, resetOnExecute, initResult, ...requestOptions } = Object.assign({}, _api, options) options2 = { before, after, shallow, resetOnExecute, initResult } const isGet = method.toLowerCase() === 'get' fn = (params, options3 = {}) => { let req if (params instanceof Request) { req = params } else { req = { ...requestOptions, ...options3, } if (isGet) { req.params = params } else { req.body = params } } return $fetch(method, url, req) } } const loading = ref(false) const result = (options.shallow === false ? ref : shallowRef)(options?.initResult) const state = ref('inited') const _before = [options.before, options2.before] const _after = [options2.after, options.after] const _fn = (params, options3) => { if (options2.resetOnExecute || options.resetOnExecute) result.value = options?.initResult loading.value = true state.value = 'loading' // eslint-disable-next-line unicorn/no-array-reduce params = _before.reduce((params, before) => (before ? before(params) ?? params : params), params) const req = Promise.resolve(fn(params, options3)) req.then( (res) => { state.value = 'success' // eslint-disable-next-line unicorn/no-array-reduce result.value = _after.reduce((res, after) => (after ? after(res) ?? res : res), res) }, (error) => { state.value = error?.name === 'AbortError' ? 'abort' : 'error' if (state.value !== 'abort') { console[error instanceof HttpError ? 'debugger' : 'error'](`[use-fetch]: `, error) } }, ).finally(() => { loading.value = false }) return req } _fn.loading = loading _fn.state = state _fn.result = result _fn.exec = _fn return _fn }