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