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" + ); + } + } +};