vue3 自定指令防抖/节流/去空格建
防抖
import type { Directive, DirectiveBinding } from "vue";
interface ElType extends HTMLElement {
handleClick: () => any;
}
const debounce: Directive = {
mounted(el: ElType, binding: DirectiveBinding) {
if (typeof binding.value !== "function") {
throw "callback must be a function";
}
let timer = null;
const delay = parseInt(binding.arg) || 500;
const handler = binding.value;
el.addEventListener(
"click",
() => {
clearTimeout(timer);
timer = setTimeout(() => {
handler();
}, delay);
},
{ passive: false }
);
},
};
export default debounce;
节流
/*
需求:防止按钮在短时间内被多次点击,使用节流函数限制规定时间内只能点击一次。
节流就是N秒内只执行一次,不管在N秒内重复调用了多少次,也只执行一次。
思路:
1、第一次点击,立即调用方法并禁用按钮,等延迟结束再次激活按钮
2、将需要触发的方法绑定在指令上
使用:给 Dom 加上 v-throttle 及回调函数即可
<el-button type="danger" icon="refresh" plain v-throttle="resetSearch">重置</el-button>
*/
// @ts-nocheck
import type { Directive, DirectiveBinding } from "vue"
interface ElType extends HTMLElement {
handleClick: () => any
disabled: boolean
}
const throttle: Directive = {
mounted(el: ElType, binding: DirectiveBinding) {
let timer = null
const delay = parseInt(binding.arg) || 500
const handler = binding.value
let lastExecTime = 0
el.addEventListener(
"click",
() => {
const now = Date.now()
if (now - lastExecTime > delay) {
handler()
lastExecTime = now
}
},
{ passive: false }
)
},
}
export default throttle
去input空格
/**
* 去除两边空格
* <el-input v-model="xxx" v-trim></el-input>
*/
function getInput(el: any) {
let inputEle
const { tagName } = el
if (tagName === "INPUT" || tagName === "TEXTAREA") {
inputEle = el
} else {
inputEle = el.querySelector("input")
if (!inputEle) {
inputEle = el.querySelector("textarea")
}
}
return inputEle
}
function dispatchEvent(el: any, type: any) {
let evt = document.createEvent("HTMLEvents")
evt.initEvent(type, true, true)
el.dispatchEvent(evt)
}
const Trim: any = {
mounted: (el: any) => {
if (!el) return
let inputEle = getInput(el)
const handler = function (event: any) {
const newVal = event.target.value.trim()
if (event.target.value != newVal) {
event.target.value = newVal
dispatchEvent(inputEle, "input")
}
}
el.inputEle = inputEle
el._blurHandler = handler
inputEle?.addEventListener("blur", handler)
},
beforeUnmount(el: any) {
const { inputEle } = el
inputEle?.removeEventListener("blur", el._blurHandler)
},
}
Trim.install = (app: any) => {
app.directive("trim", Trim)
}
export default Trim
注册
import { App } from "vue";
import trim from "./trim/index";
import debounce from "./debounce/index";
import throttle from "./throttle/index";
const directivesList: any = {
trim,
debounce,
throttle,
};
const directives = {
install: function (app: App<Element>) {
Object.keys(directivesList).forEach((key) => {
app.directive(key, directivesList[key]);
});
},
};
export default directives;
引入main.ts
import directives from '@/directives/index';
import directives from '@/directives/index';
结束!!!