From d85049660135c360b3c56e43af605bb1a8c996bd Mon Sep 17 00:00:00 2001 From: xiaoxian521 <1923740402@qq.com> Date: Mon, 12 Jun 2023 13:53:54 +0800 Subject: [PATCH 1/3] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0`=E9=98=B2?= =?UTF-8?q?=E6=8A=96`=E5=92=8C`=E8=8A=82=E6=B5=81`=E6=8C=87=E4=BB=A4?= =?UTF-8?q?=E5=B9=B6=E8=A7=84=E8=8C=83=E8=87=AA=E5=AE=9A=E4=B9=89=E6=8C=87?= =?UTF-8?q?=E4=BB=A4=E7=94=A8=E6=B3=95=E9=94=99=E8=AF=AF=E6=97=B6=E7=9A=84?= =?UTF-8?q?=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/directives/auth/index.ts | 4 ++- src/directives/index.ts | 1 + src/directives/optimize/index.ts | 55 ++++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 src/directives/optimize/index.ts diff --git a/src/directives/auth/index.ts b/src/directives/auth/index.ts index 627ea896e..62ca87c2e 100644 --- a/src/directives/auth/index.ts +++ b/src/directives/auth/index.ts @@ -7,7 +7,9 @@ export const auth: Directive = { if (value) { !hasAuth(value) && el.parentNode?.removeChild(el); } else { - throw new Error("need auths! Like v-auth=\"['btn.add','btn.edit']\""); + throw new Error( + "[Directive: auth]: need auths! Like v-auth=\"['btn.add','btn.edit']\"" + ); } } }; diff --git a/src/directives/index.ts b/src/directives/index.ts index 97ccf7649..f744f313d 100644 --- a/src/directives/index.ts +++ b/src/directives/index.ts @@ -1 +1,2 @@ export * from "./auth"; +export * from "./optimize"; diff --git a/src/directives/optimize/index.ts b/src/directives/optimize/index.ts new file mode 100644 index 000000000..d56f23b7c --- /dev/null +++ b/src/directives/optimize/index.ts @@ -0,0 +1,55 @@ +import { + isFunction, + isObject, + isArray, + debounce, + throttle +} from "@pureadmin/utils"; +import { useEventListener } from "@vueuse/core"; +import { Directive, type DirectiveBinding } from "vue"; + +/** 防抖(v-optimize或v-optimize:debounce)、节流(v-optimize:throttle)指令 */ +export const optimize: Directive = { + mounted(el: HTMLElement, binding: DirectiveBinding) { + const { value } = binding; + const optimizeType = binding.arg ?? "debounce"; + const type = ["debounce", "throttle"].find(t => t === optimizeType); + if (type) { + if (value && value.event && isFunction(value.fn)) { + let params = value?.params; + if (params) { + if (isArray(params) || isObject(params)) { + params = isObject(params) ? Array.of(params) : params; + } else { + throw new Error( + "[Directive: optimize]: `params` must be an array or object" + ); + } + } + // Register using addEventListener on mounted, and removeEventListener automatically on unmounted + useEventListener( + el, + value.event, + type === "debounce" + ? debounce( + params ? () => value.fn(...params) : value.fn, + value?.timeout ?? 200, + value?.immediate ?? false + ) + : throttle( + params ? () => value.fn(...params) : value.fn, + value?.timeout ?? 200 + ) + ); + } else { + throw new Error( + "[Directive: optimize]: `event` and `fn` are required, and `fn` must be a function" + ); + } + } else { + throw new Error( + "[Directive: optimize]: only `debounce` and `throttle` are supported" + ); + } + } +}; From 3fd9b156987f29a405c15e054e71eac8ea6d9fdc Mon Sep 17 00:00:00 2001 From: xiaoxian521 <1923740402@qq.com> Date: Mon, 12 Jun 2023 15:34:44 +0800 Subject: [PATCH 2/3] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E5=A4=8D=E5=88=B6=E8=87=AA=E5=AE=9A=E4=B9=89=E6=8C=87?= =?UTF-8?q?=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/directives/copy/index.ts | 33 +++++++++++++++++++++++++++++++++ src/directives/index.ts | 1 + 2 files changed, 34 insertions(+) create mode 100644 src/directives/copy/index.ts diff --git a/src/directives/copy/index.ts b/src/directives/copy/index.ts new file mode 100644 index 000000000..11db44618 --- /dev/null +++ b/src/directives/copy/index.ts @@ -0,0 +1,33 @@ +import { message } from "@/utils/message"; +import { useEventListener } from "@vueuse/core"; +import { copyTextToClipboard } from "@pureadmin/utils"; +import { Directive, type DirectiveBinding } from "vue"; + +interface CopyEl extends HTMLElement { + copyValue: string; +} + +/** 文本复制指令(默认双击复制) */ +export const copy: Directive = { + mounted(el: CopyEl, binding: DirectiveBinding) { + const { value } = binding; + if (value) { + el.copyValue = value; + const arg = binding.arg ?? "dblclick"; + // Register using addEventListener on mounted, and removeEventListener automatically on unmounted + useEventListener(el, arg, () => { + const success = copyTextToClipboard(el.copyValue); + success + ? message("复制成功", { type: "success" }) + : message("复制失败", { type: "error" }); + }); + } else { + throw new Error( + '[Directive: copy]: need value! Like v-copy="modelValue"' + ); + } + }, + updated(el: CopyEl, binding: DirectiveBinding) { + el.copyValue = binding.value; + } +}; diff --git a/src/directives/index.ts b/src/directives/index.ts index f744f313d..5e81e0657 100644 --- a/src/directives/index.ts +++ b/src/directives/index.ts @@ -1,2 +1,3 @@ export * from "./auth"; +export * from "./copy"; export * from "./optimize"; From aec2a3542415b37e5d149ea8f6bdc95374c76756 Mon Sep 17 00:00:00 2001 From: xiaoxian521 <1923740402@qq.com> Date: Mon, 12 Jun 2023 21:11:31 +0800 Subject: [PATCH 3/3] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=98=B2?= =?UTF-8?q?=E6=8A=96=E3=80=81=E6=88=AA=E6=B5=81=E3=80=81=E5=A4=8D=E5=88=B6?= =?UTF-8?q?=E8=87=AA=E5=AE=9A=E4=B9=89=E6=8C=87=E4=BB=A4=E4=BD=BF=E7=94=A8?= =?UTF-8?q?=E7=A4=BA=E4=BE=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/en.yaml | 1 + locales/zh-CN.yaml | 1 + src/directives/optimize/index.ts | 2 +- src/router/modules/able.ts | 9 +++ src/views/able/directives.vue | 117 +++++++++++++++++++++++++++++++ 5 files changed, 129 insertions(+), 1 deletion(-) create mode 100644 src/views/able/directives.vue diff --git a/locales/en.yaml b/locales/en.yaml index 96a4ccbea..9eed96fcc 100644 --- a/locales/en.yaml +++ b/locales/en.yaml @@ -68,6 +68,7 @@ menus: hsguide: Guide hsAble: Able hsMenuTree: Menu Tree + hsOptimize: Debounce、Throttle、Copy Directives hsWatermark: Water Mark hsPrint: Print hsDownload: Download diff --git a/locales/zh-CN.yaml b/locales/zh-CN.yaml index 8cb2f1584..eb34b895e 100644 --- a/locales/zh-CN.yaml +++ b/locales/zh-CN.yaml @@ -68,6 +68,7 @@ menus: hsguide: 引导页 hsAble: 功能 hsMenuTree: 菜单树结构 + hsOptimize: 防抖、截流、复制指令 hsWatermark: 水印 hsPrint: 打印 hsDownload: 下载 diff --git a/src/directives/optimize/index.ts b/src/directives/optimize/index.ts index d56f23b7c..43ac38ac8 100644 --- a/src/directives/optimize/index.ts +++ b/src/directives/optimize/index.ts @@ -38,7 +38,7 @@ export const optimize: Directive = { ) : throttle( params ? () => value.fn(...params) : value.fn, - value?.timeout ?? 200 + value?.timeout ?? 1000 ) ); } else { diff --git a/src/router/modules/able.ts b/src/router/modules/able.ts index aaca0bdf5..35e5bef0f 100644 --- a/src/router/modules/able.ts +++ b/src/router/modules/able.ts @@ -10,6 +10,15 @@ export default { rank: able }, children: [ + { + path: "/able/directives", + name: "Directives", + component: () => import("@/views/able/directives.vue"), + meta: { + title: $t("menus.hsOptimize"), + extraIcon: "IF-pure-iconfont-new svg" + } + }, { path: "/able/watermark", name: "WaterMark", diff --git a/src/views/able/directives.vue b/src/views/able/directives.vue new file mode 100644 index 000000000..f3e566536 --- /dev/null +++ b/src/views/able/directives.vue @@ -0,0 +1,117 @@ + + +