1,新建longTime.ts文件
import type { Directive, DirectiveBinding } from "vue";
const directive: Directive = {
mounted(el: HTMLElement, binding: DirectiveBinding) {
if (typeof binding.value !== "function") {
throw "callback must be a function";
}
// 定义变量
let pressTimer: any = null;
// 创建计时器( 2秒后执行函数 )
const start = (e: any) => {
if (e.button) {
console.log(e.type,'e.type',e.button,'e.button');
if (e.type === "click" && e.button !== 0) {
return;
}
}
if (pressTimer === null) {
pressTimer = setTimeout(() => {
handler(e);
}, 1000);
}
};
// 取消计时器
const cancel = () => {
if (pressTimer !== null) {
clearTimeout(pressTimer);
pressTimer = null;
}
};
// 运行函数
const handler = (e: MouseEvent | TouchEvent) => {
binding.value(e);
};
// 添加事件监听器
el.addEventListener("mousedown", start);
el.addEventListener("touchstart", start);
// 取消计时器
el.addEventListener("click", cancel);
el.addEventListener("mouseout", cancel);
el.addEventListener("touchend", cancel);
el.addEventListener("touchcancel", cancel);
}
};
export default directive;
2注册自定义指令
新建ts文件并且引入longTime.ts
import longpress from "./longTime";
import { App } from "vue";
const directivesList:any= { //注意其any类型,否则会报错
longpress,
}
const directives = {
install: function (app: App<Element>) {
Object.keys(directivesList).forEach(key => {
// 注册自定义指令
app.directive(key, directivesList[key]);
});
}
};
export default directives
3 在main.js全局注册
import directives from './hooks/index'
createApp(App).use(directives)
4 在页面使用
v-longpress="longpress"
v-longpress="() =>{longpress(item._id)}"
//注:这里为了使typeof binding.value等于一个方法,不能直接进行传参
Vue 的指令预期得到的值是一个 JavaScript 表达式,除了 v-on 和 v-for 这两个特殊指令外,其他的指令会自动计算该表达式的值,将最终的计算结果传递给指令。所以自定义的指令不能用v-longpress="longpress(item._id)" 的形式绑定函数值,因为 longpress(item._id) 作为一个 JavaScript 表达式会被立即执行,最终会将其返回值传递给指令。
利用指令的值预期得到一个 JavaScript 表达式的特性,可以为其值绑定一个包装后的函数,从而实现传递参数的目的。如下
v-longpress="() =>{longpress(item._id)}">