From b9b917cf5e4afb2ccaba97802fa2dc2e39328b38 Mon Sep 17 00:00:00 2001 From: ClariS <1457715339@qq.com> Date: Mon, 9 Jan 2023 16:39:38 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=B0=81=E8=A3=85=E5=85=A8=E5=B1=8F=20?= =?UTF-8?q?loading=20hook=20(#41)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/{select.ts => mock.ts} | 24 +++++++- src/hooks/useFullscreenLoading.ts | 60 +++++++++++++++++++ src/router/index.ts | 26 ++++++-- .../index.vue => hooks/use-fetch-select.vue} | 2 +- src/views/hooks/use-fullscreen-loading.vue | 41 +++++++++++++ 5 files changed, 143 insertions(+), 10 deletions(-) rename src/api/{select.ts => mock.ts} (61%) create mode 100644 src/hooks/useFullscreenLoading.ts rename src/views/{select/index.vue => hooks/use-fetch-select.vue} (89%) create mode 100644 src/views/hooks/use-fullscreen-loading.vue diff --git a/src/api/select.ts b/src/api/mock.ts similarity index 61% rename from src/api/select.ts rename to src/api/mock.ts index 3657cd5..e9a0007 100644 --- a/src/api/select.ts +++ b/src/api/mock.ts @@ -1,6 +1,3 @@ -// import { request } from "@/utils/service" - -/** 查 */ export function getRemoteSelectData() { return new Promise((resolve, reject) => { setTimeout(() => { @@ -33,3 +30,24 @@ export function getRemoteSelectData() { }, 3000) }) } + +export interface IBirdsItem { + id: number + name: string +} + +export const getBirds = () => { + return new Promise((resolve) => { + setTimeout(() => { + resolve([...Array(5)].map((_t, index) => ({ id: index, name: `t${index}` }))) + }, 1000) + }) +} + +export const getCars = (id: number) => { + return new Promise((_resolve, reject) => { + setTimeout(() => { + reject(new Error("sorry" + id)) + }, 1000) + }) +} diff --git a/src/hooks/useFullscreenLoading.ts b/src/hooks/useFullscreenLoading.ts new file mode 100644 index 0000000..64e14f9 --- /dev/null +++ b/src/hooks/useFullscreenLoading.ts @@ -0,0 +1,60 @@ +import { ElLoading, LoadingOptions } from "element-plus" + +const defaultOption = { + lock: true, + text: "加载中...", + background: "rgba(0, 0, 0, 0.7)" +} + +interface ILoading { + close: () => void +} + +/** + * 传入一个方法 fn,在它执行周期内,加上「全屏」loading + * 如果: + * 1. fn 是同步方法,结束后隐藏 loading + * 2. 如果是异步方法,resolve 后隐藏 loading + * 3. 报错后隐藏 loading 并抛出错误 + * @param {*} fn 函数 + * @param options + * @returns Function 一个新的函数,去执行它吧 + */ +export const useFullscreenLoading = ( + fn: (...args: any[]) => T, + options: LoadingOptions = {} +): ((...args: any[]) => Promise) => { + let loading: ILoading | undefined + const showLoading = (options: LoadingOptions) => { + loading = ElLoading.service(options) + } + + const hideLoading = () => { + loading && loading.close() + } + const _options = { ...defaultOption, ...options } + const newFn = (...args: any[]) => { + try { + showLoading(_options) + const result = fn(...args) + const isPromise = result instanceof Promise + if (!isPromise) { + hideLoading() + return Promise.resolve(result) + } + return result + .then((res: any) => { + hideLoading() + return res + }) + .catch((err: Error) => { + hideLoading() + throw err + }) + } catch (err) { + hideLoading() + throw err + } + } + return newFn +} diff --git a/src/router/index.ts b/src/router/index.ts index 1aed380..ba71697 100644 --- a/src/router/index.ts +++ b/src/router/index.ts @@ -190,16 +190,30 @@ export const constantRoutes: RouteRecordRaw[] = [ ] }, { - path: "/select", + path: "/hooks", component: Layout, + redirect: "/hooks/use-fetch-select", + name: "Hooks", + meta: { + title: "hooks", + elIcon: "Menu", + alwaysShow: true + }, children: [ { - path: "", - component: () => import("@/views/select/index.vue"), - name: "Select", + path: "use-fetch-select", + component: () => import("@/views/hooks/use-fetch-select.vue"), + name: "UseFetchSelect", meta: { - title: "下拉框", - svgIcon: "component" + title: "useFetchSelect" + } + }, + { + path: "use-fullscreen-loading", + component: () => import("@/views/hooks/use-fullscreen-loading.vue"), + name: "UseFullscreenLoading", + meta: { + title: "useFullscreenLoading" } } ] diff --git a/src/views/select/index.vue b/src/views/hooks/use-fetch-select.vue similarity index 89% rename from src/views/select/index.vue rename to src/views/hooks/use-fetch-select.vue index f0234ba..425cc0d 100644 --- a/src/views/select/index.vue +++ b/src/views/hooks/use-fetch-select.vue @@ -1,5 +1,5 @@