From b8200125dc6cb782a73da4cb90bd162e4df0bad9 Mon Sep 17 00:00:00 2001 From: xiaoming <1923740402@qq.com> Date: Fri, 23 Jun 2023 11:17:39 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=95=BF=E6=8C=89?= =?UTF-8?q?=E6=8C=87=E4=BB=A4=E5=8F=8A=E4=BD=BF=E7=94=A8=E7=A4=BA=E4=BE=8B?= =?UTF-8?q?=EF=BC=8C=E8=AF=A5=E9=95=BF=E6=8C=89=E6=8C=87=E4=BB=A4=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E8=87=AA=E5=AE=9A=E4=B9=89=E6=97=B6=E9=95=BF=E7=9A=84?= =?UTF-8?q?=E6=8C=81=E7=BB=AD=E5=9B=9E=E8=B0=83=20(#620)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- locales/en.yaml | 2 +- locales/zh-CN.yaml | 2 +- src/directives/auth/index.ts | 2 +- src/directives/copy/index.ts | 2 +- src/directives/index.ts | 1 + src/directives/longpress/index.ts | 63 +++++++++++++++++++++++++++++++ src/directives/optimize/index.ts | 2 +- src/views/able/directives.vue | 41 +++++++++++++++++++- 8 files changed, 109 insertions(+), 6 deletions(-) create mode 100644 src/directives/longpress/index.ts diff --git a/locales/en.yaml b/locales/en.yaml index e72a50e29..8030d000b 100644 --- a/locales/en.yaml +++ b/locales/en.yaml @@ -68,7 +68,7 @@ menus: hsguide: Guide hsAble: Able hsMenuTree: Menu Tree - hsOptimize: Debounce、Throttle、Copy Directives + hsOptimize: Debounce、Throttle、Copy、Longpress Directives hsWatermark: Water Mark hsPrint: Print hsDownload: Download diff --git a/locales/zh-CN.yaml b/locales/zh-CN.yaml index 5e56ac0b3..fe207f9a7 100644 --- a/locales/zh-CN.yaml +++ b/locales/zh-CN.yaml @@ -68,7 +68,7 @@ menus: hsguide: 引导页 hsAble: 功能 hsMenuTree: 菜单树结构 - hsOptimize: 防抖、截流、复制指令 + hsOptimize: 防抖、截流、复制、长按指令 hsWatermark: 水印 hsPrint: 打印 hsDownload: 下载 diff --git a/src/directives/auth/index.ts b/src/directives/auth/index.ts index 62ca87c2e..a7a4f2216 100644 --- a/src/directives/auth/index.ts +++ b/src/directives/auth/index.ts @@ -1,5 +1,5 @@ import { hasAuth } from "@/router/utils"; -import { Directive, type DirectiveBinding } from "vue"; +import type { Directive, DirectiveBinding } from "vue"; export const auth: Directive = { mounted(el: HTMLElement, binding: DirectiveBinding) { diff --git a/src/directives/copy/index.ts b/src/directives/copy/index.ts index 11db44618..8e9783381 100644 --- a/src/directives/copy/index.ts +++ b/src/directives/copy/index.ts @@ -1,7 +1,7 @@ import { message } from "@/utils/message"; import { useEventListener } from "@vueuse/core"; import { copyTextToClipboard } from "@pureadmin/utils"; -import { Directive, type DirectiveBinding } from "vue"; +import type { Directive, DirectiveBinding } from "vue"; interface CopyEl extends HTMLElement { copyValue: string; diff --git a/src/directives/index.ts b/src/directives/index.ts index 5e81e0657..f4238c9af 100644 --- a/src/directives/index.ts +++ b/src/directives/index.ts @@ -1,3 +1,4 @@ export * from "./auth"; export * from "./copy"; +export * from "./longpress"; export * from "./optimize"; diff --git a/src/directives/longpress/index.ts b/src/directives/longpress/index.ts new file mode 100644 index 000000000..544278448 --- /dev/null +++ b/src/directives/longpress/index.ts @@ -0,0 +1,63 @@ +import { useEventListener } from "@vueuse/core"; +import type { Directive, DirectiveBinding } from "vue"; +import { subBefore, subAfter, isFunction } from "@pureadmin/utils"; + +export const longpress: Directive = { + mounted(el: HTMLElement, binding: DirectiveBinding) { + const cb = binding.value; + if (cb && isFunction(cb)) { + let timer = null; + let interTimer = null; + let num = 500; + let interNum = null; + const isInter = binding?.arg?.includes(":") ?? false; + + if (isInter) { + num = Number(subBefore(binding.arg, ":")); + interNum = Number(subAfter(binding.arg, ":")); + } else if (binding.arg) { + num = Number(binding.arg); + } + + const clear = () => { + if (timer) { + clearTimeout(timer); + timer = null; + } + if (interTimer) { + clearInterval(interTimer); + interTimer = null; + } + }; + + const onDownInter = (ev: PointerEvent) => { + ev.preventDefault(); + if (interTimer === null) { + interTimer = setInterval(() => cb(), interNum); + } + }; + + const onDown = (ev: PointerEvent) => { + clear(); + ev.preventDefault(); + if (timer === null) { + timer = isInter + ? setTimeout(() => { + cb(); + onDownInter(ev); + }, num) + : setTimeout(() => cb(), num); + } + }; + + // Register using addEventListener on mounted, and removeEventListener automatically on unmounted + useEventListener(el, "pointerdown", onDown); + useEventListener(el, "pointerup", clear); + useEventListener(el, "pointerleave", clear); + } else { + throw new Error( + '[Directive: longpress]: need callback and callback must be a function! Like v-longpress="callback"' + ); + } + } +}; diff --git a/src/directives/optimize/index.ts b/src/directives/optimize/index.ts index 43ac38ac8..5fbdd1fec 100644 --- a/src/directives/optimize/index.ts +++ b/src/directives/optimize/index.ts @@ -6,7 +6,7 @@ import { throttle } from "@pureadmin/utils"; import { useEventListener } from "@vueuse/core"; -import { Directive, type DirectiveBinding } from "vue"; +import type { Directive, DirectiveBinding } from "vue"; /** 防抖(v-optimize或v-optimize:debounce)、节流(v-optimize:throttle)指令 */ export const optimize: Directive = { diff --git a/src/views/able/directives.vue b/src/views/able/directives.vue index f3e566536..e032b24ba 100644 --- a/src/views/able/directives.vue +++ b/src/views/able/directives.vue @@ -13,6 +13,9 @@ const searchFour = ref(""); const searchFive = ref(""); const searchSix = ref("copy"); const text = ref("可复制的文本"); +const long = ref(false); +const cbText = ref(""); +const idx = ref(0); function onInput() { message(search.value); @@ -30,13 +33,30 @@ function onInputFour() { function onInputFive({ name, sex }) { message(`${name}${sex}${searchFive.value}`); } + +function onLongpress() { + long.value = true; +} +function onCustomLongpress() { + long.value = true; +} +function onCbLongpress() { + idx.value += 1; + long.value = true; + cbText.value = `持续回调${idx.value}次`; +} +function onReset() { + long.value = false; + cbText.value = ""; + idx.value = 0; +}