From e270308f10c91f3e667c46330850a4c836f61023 Mon Sep 17 00:00:00 2001 From: pany <939630029@qq.com> Date: Wed, 1 Feb 2023 18:09:44 +0800 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E5=86=99=20useFetchSelect?= =?UTF-8?q?=20=E4=B8=8E=20useFullscreenLoading?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/hook-demo/use-fetch-select.ts | 36 +++++++++++ src/api/hook-demo/use-fullscreen-loading.ts | 24 +++++++ src/api/mock.ts | 53 ---------------- src/hooks/useFetchSelect.ts | 63 +++++++++---------- src/hooks/useFullscreenLoading.ts | 41 ++++++------ src/hooks/usePagination.ts | 2 +- src/router/index.ts | 12 ++-- src/views/hook-demo/use-fetch-select.vue | 20 ++++++ .../hook-demo/use-fullscreen-loading.vue | 44 +++++++++++++ src/views/hooks/use-fetch-select.vue | 18 ------ src/views/hooks/use-fullscreen-loading.vue | 41 ------------ 11 files changed, 179 insertions(+), 175 deletions(-) create mode 100644 src/api/hook-demo/use-fetch-select.ts create mode 100644 src/api/hook-demo/use-fullscreen-loading.ts delete mode 100644 src/api/mock.ts create mode 100644 src/views/hook-demo/use-fetch-select.vue create mode 100644 src/views/hook-demo/use-fullscreen-loading.vue delete mode 100644 src/views/hooks/use-fetch-select.vue delete mode 100644 src/views/hooks/use-fullscreen-loading.vue diff --git a/src/api/hook-demo/use-fetch-select.ts b/src/api/hook-demo/use-fetch-select.ts new file mode 100644 index 0000000..5998e40 --- /dev/null +++ b/src/api/hook-demo/use-fetch-select.ts @@ -0,0 +1,36 @@ +/** 模拟接口响应数据 */ +const SELECT_DATA = { + code: 0, + data: [ + { + label: "苹果", + value: 1 + }, + { + label: "香蕉", + value: 2 + }, + { + label: "橘子", + value: 3, + disabled: true + } + ], + message: "获取 Select 数据成功" +} + +/** 模拟接口 */ +export function getSelectDataApi() { + return new Promise((resolve, reject) => { + // 模拟接口响应时间 2s + setTimeout(() => { + // 模拟接口调用成功 + if (Math.random() < 0.8) { + resolve(SELECT_DATA) + } else { + // 模拟接口调用出错 + reject(new Error("接口发生错误")) + } + }, 2000) + }) +} diff --git a/src/api/hook-demo/use-fullscreen-loading.ts b/src/api/hook-demo/use-fullscreen-loading.ts new file mode 100644 index 0000000..6f86104 --- /dev/null +++ b/src/api/hook-demo/use-fullscreen-loading.ts @@ -0,0 +1,24 @@ +/** 模拟接口响应数据 */ +const SUCCESS_DATA = { + code: 0, + data: {}, + message: "获取成功" +} + +/** 模拟请求接口成功 */ +export function getSuccessApi() { + return new Promise((resolve) => { + setTimeout(() => { + resolve(SUCCESS_DATA) + }, 1000) + }) +} + +/** 模拟请求接口失败 */ +export function getErrorApi() { + return new Promise((_resolve, reject) => { + setTimeout(() => { + reject(new Error("发生错误")) + }, 1000) + }) +} diff --git a/src/api/mock.ts b/src/api/mock.ts deleted file mode 100644 index d16c594..0000000 --- a/src/api/mock.ts +++ /dev/null @@ -1,53 +0,0 @@ -export function getRemoteSelectData() { - return new Promise((resolve, reject) => { - setTimeout(() => { - // 模拟接口调用有概率出错 - if (Math.random() > 0.5) { - resolve({ - code: 0, - data: [ - { - key: 1, - label: "苹果", - value: 1 - }, - { - key: 2, - label: "香蕉", - value: 2 - }, - { - key: 3, - label: "橘子", - value: 3 - } - ], - message: "成功" - }) - } else { - reject(new Error("不小心出错了!")) - } - }, 3000) - }) -} - -export interface IComicsItem { - id: number - name: string -} - -export const getComics = () => { - return new Promise((resolve) => { - setTimeout(() => { - resolve([...Array(5)].map((_t, index) => ({ id: index, name: `c${index}` }))) - }, 1000) - }) -} - -export const getAnimations = (id: number) => { - return new Promise((_resolve, reject) => { - setTimeout(() => { - reject(new Error(`Sorry, there is an error here. The error id is ${id}`)) - }, 1000) - }) -} diff --git a/src/hooks/useFetchSelect.ts b/src/hooks/useFetchSelect.ts index d3812cf..02c623c 100644 --- a/src/hooks/useFetchSelect.ts +++ b/src/hooks/useFetchSelect.ts @@ -1,51 +1,44 @@ -import { onMounted, ref } from "vue" +import { ref, onMounted } from "vue" -// 定义下拉框接收的数据格式 -export interface SelectOption { - value: string +type OptionValueType = string | number + +/** Select 需要的数据格式 */ +interface ISelectOption { + value: OptionValueType label: string disabled?: boolean - key?: string } -// 定义入参格式 -interface FetchSelectProps { - apiFun: () => Promise +/** 接口响应格式 */ +interface IApiData { + code: number + data: ISelectOption[] + message: string } -export function useFetchSelect(props: FetchSelectProps) { - const { apiFun } = props +/** 入参格式,暂时只需要传递 api 函数即可 */ +interface IFetchSelectProps { + api: () => Promise +} - const options = ref([]) +export function useFetchSelect(props: IFetchSelectProps) { + const { api } = props - const loading = ref(false) + const loading = ref(false) + const options = ref([]) + const value = ref("") - const selectedValue = ref("") - - /* 调用接口请求数据 */ + /** 调用接口获取数据 */ const loadData = () => { loading.value = true options.value = [] - return apiFun().then( - (res) => { - loading.value = false + api() + .then((res) => { options.value = res.data - return res.data - }, - (err) => { - // 未知错误,可能是代码抛出的错误,或是网络错误 + }) + .finally(() => { loading.value = false - options.value = [ - { - value: "-1", - label: err.message, - disabled: true - } - ] - // 接着抛出错误 - return Promise.reject(err) - } - ) + }) } onMounted(() => { @@ -53,8 +46,8 @@ export function useFetchSelect(props: FetchSelectProps) { }) return { - options, loading, - selectedValue + options, + value } } diff --git a/src/hooks/useFullscreenLoading.ts b/src/hooks/useFullscreenLoading.ts index 64e14f9..46d810c 100644 --- a/src/hooks/useFullscreenLoading.ts +++ b/src/hooks/useFullscreenLoading.ts @@ -1,53 +1,53 @@ -import { ElLoading, LoadingOptions } from "element-plus" +import { type LoadingOptions, ElLoading } from "element-plus" -const defaultOption = { +const defaultOptions = { lock: true, - text: "加载中...", - background: "rgba(0, 0, 0, 0.7)" + text: "加载中..." } -interface ILoading { +interface ILoadingInstance { close: () => void } /** - * 传入一个方法 fn,在它执行周期内,加上「全屏」loading + * 传入一个函数 fn,在它执行周期内,加上「全屏」loading, * 如果: - * 1. fn 是同步方法,结束后隐藏 loading - * 2. 如果是异步方法,resolve 后隐藏 loading + * 1. fn 如果是同步函数,执行结束后隐藏 loading + * 2. fn 如果是 Promise,resolve 或 reject 后隐藏 loading * 3. 报错后隐藏 loading 并抛出错误 * @param {*} fn 函数 - * @param options + * @param options LoadingOptions * @returns Function 一个新的函数,去执行它吧 */ -export const useFullscreenLoading = ( - fn: (...args: any[]) => T, +export function useFullscreenLoading( + fn: (...args: any[]) => T | Promise, options: LoadingOptions = {} -): ((...args: any[]) => Promise) => { - let loading: ILoading | undefined +): (...args: any[]) => Promise { + let loadingInstance: ILoadingInstance const showLoading = (options: LoadingOptions) => { - loading = ElLoading.service(options) + loadingInstance = ElLoading.service(options) } - const hideLoading = () => { - loading && loading.close() + loadingInstance && loadingInstance.close() } - const _options = { ...defaultOption, ...options } - const newFn = (...args: any[]) => { + const _options = { ...defaultOptions, ...options } + return (...args: any[]) => { try { showLoading(_options) const result = fn(...args) const isPromise = result instanceof Promise + // 同步函数 if (!isPromise) { hideLoading() return Promise.resolve(result) } + // Promise return result - .then((res: any) => { + .then((res) => { hideLoading() return res }) - .catch((err: Error) => { + .catch((err) => { hideLoading() throw err }) @@ -56,5 +56,4 @@ export const useFullscreenLoading = ( throw err } } - return newFn } diff --git a/src/hooks/usePagination.ts b/src/hooks/usePagination.ts index 9edd1f3..d860884 100644 --- a/src/hooks/usePagination.ts +++ b/src/hooks/usePagination.ts @@ -25,7 +25,7 @@ const defaultPaginationData: IDefaultPaginationData = { layout: "total, sizes, prev, pager, next, jumper" } -export const usePagination = (_paginationData: IPaginationData = {}) => { +export function usePagination(_paginationData: IPaginationData = {}) { /** 合并分页参数 */ const paginationData = reactive(Object.assign({ ...defaultPaginationData }, _paginationData)) diff --git a/src/router/index.ts b/src/router/index.ts index ba71697..e5d4c73 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -190,19 +190,19 @@ export const constantRoutes: RouteRecordRaw[] = [ ] }, { - path: "/hooks", + path: "/hook-demo", component: Layout, - redirect: "/hooks/use-fetch-select", - name: "Hooks", + redirect: "/hook-demo/use-fetch-select", + name: "HookDemo", meta: { - title: "hooks", + title: "hook 示例", elIcon: "Menu", alwaysShow: true }, children: [ { path: "use-fetch-select", - component: () => import("@/views/hooks/use-fetch-select.vue"), + component: () => import("@/views/hook-demo/use-fetch-select.vue"), name: "UseFetchSelect", meta: { title: "useFetchSelect" @@ -210,7 +210,7 @@ export const constantRoutes: RouteRecordRaw[] = [ }, { path: "use-fullscreen-loading", - component: () => import("@/views/hooks/use-fullscreen-loading.vue"), + component: () => import("@/views/hook-demo/use-fullscreen-loading.vue"), name: "UseFullscreenLoading", meta: { title: "useFullscreenLoading" diff --git a/src/views/hook-demo/use-fetch-select.vue b/src/views/hook-demo/use-fetch-select.vue new file mode 100644 index 0000000..ecf144c --- /dev/null +++ b/src/views/hook-demo/use-fetch-select.vue @@ -0,0 +1,20 @@ + + + diff --git a/src/views/hook-demo/use-fullscreen-loading.vue b/src/views/hook-demo/use-fullscreen-loading.vue new file mode 100644 index 0000000..460444a --- /dev/null +++ b/src/views/hook-demo/use-fullscreen-loading.vue @@ -0,0 +1,44 @@ + + + diff --git a/src/views/hooks/use-fetch-select.vue b/src/views/hooks/use-fetch-select.vue deleted file mode 100644 index f8f9467..0000000 --- a/src/views/hooks/use-fetch-select.vue +++ /dev/null @@ -1,18 +0,0 @@ - - - diff --git a/src/views/hooks/use-fullscreen-loading.vue b/src/views/hooks/use-fullscreen-loading.vue deleted file mode 100644 index a8958aa..0000000 --- a/src/views/hooks/use-fullscreen-loading.vue +++ /dev/null @@ -1,41 +0,0 @@ - - -