【VUE3】自定义防抖指令

目前在使用Vue3+TypeScript开发前端项目。时长遇到"手抖"选手,导致多次请求等问题。

Vue 3 允许你创建自定义指令,以便在 DOM 上应用一些特殊的行为。自定义指令具有几个可用的钩子函数,如 bind、inserted、update、componentUpdated 和 unbind,它们会在指令的不同生命周期阶段被调用。

下面是如何在 Vue 3 中创建一个自定义指令的基本步骤:

定义自定义指令

你可以在组件内部定义指令,也可以全局定义它们。

局部定义(在组件内部):

javascript 复制代码
export default {
  directives: {
    focus: {
      // 当被绑定的元素插入到 DOM 中时调用
      inserted: function (el) {
        el.focus()
      }
    }
  }
}

全局定义

javascript 复制代码
const app = Vue.createApp({})

app.directive('focus', {
  inserted: function (el) {
    el.focus()
  }
})

使用自定义指令

在你的模板中,你可以像使用内置指令一样使用自定义指令:

html 复制代码
<template>
  <input v-focus>
</template>

使用钩子函数

除了 inserted,你还可以使用其他钩子函数,如 bind、update、componentUpdated 和 unbind。

例如,下面的指令会在元素的值更新时改变其颜色:

javascript 复制代码
app.directive('color-on-update', {
  bind(el, binding, vnode) {
    el.style.color = 'black'
  },
  update(el, binding, vnode, prevVnode) {
    el.style.color = 'red'
  }
})

然后,你可以在模板中这样使用它:

html 复制代码
<template>
  <p v-color-on-update="someReactiveProperty">This text will turn red when `someReactiveProperty` changes.</p>
</template>

传递参数给自定义指令

你可以通过指令的值、修饰符或表达式传递参数给自定义指令。例如:

html 复制代码
<template>
  <p v-highlight="'yellow'">Highlighted text</p>
</template>

在自定义指令中,你可以通过 binding.value 访问这个值:

javascript 复制代码
app.directive('highlight', {
  bind(el, binding) {
    el.style.backgroundColor = binding.value
  }
})

动态指令参数

Vue 3 还支持动态指令参数,这意味着你可以根据组件的状态动态地改变指令的行为。例如:

html 复制代码
<template>
  <p v-highlight:[dynamicColor]>Dynamically highlighted text</p>
</template>

<script>
export default {
  data() {
    return {
      dynamicColor: 'blue'
    }
  }
}
</script>

在自定义指令中,你可以这样处理动态参数:

javascript 复制代码
app.directive('highlight', {
  bind(el, binding) {
    const color = binding.arg || 'defaultColor' // 如果动态参数不存在,则使用默认值
    el.style.backgroundColor = color
  }
})

通过这些方法,我们来创建一个防抖指令

typescript 复制代码
// 定义防止重复点击的指令
export const preventReClick = {
    created(el:any, binding:any, vnode:any, prevVnode:any) {
        console.log(vnode,prevVnode);
        
        el.addEventListener('click', (e:any)=>customClick(e,binding,el));
    },
    // 离开一定要销毁卸载
    unmounted(el:any, binding:any, vnode:any) {
        console.log(binding,vnode);
        
        el.removeEventListener('click', customClick);
    },
};
// 逻辑封装
const customClick = (e:any,binding:any,el:any) => {
//阻止事件冒泡
    e.stopPropagation()
        if (!el.disabled) { // 判断条件
            el.disabled = true
            setTimeout(() => {
                el.disabled = false
            },binding.arg||1000)
            // 正常触发点击事件
            binding.value();
        } else {
            // 已经成功拦截点击事件
            console.log('已经成功拦截点击事件');
        };
    
};
//指令抛出
export const setupAuthDirective = (app:any) => {
  app.directive('click', preventReClick);
};
    
相关推荐
龚思凯5 分钟前
TypeScript 中 typeof 的全面解析:从基础用法到高级技巧
前端·typescript
jstart千语1 小时前
【vue3学习】vue3入门
前端·javascript·vue.js·typescript·vue
向明天乄1 小时前
Maotu流程图编辑器:Vue3项目中的集成实战与自定义流程开发指南
javascript·编辑器·vue·流程图
struggle20257 小时前
RushDB开源程序 是现代应用程序和 AI 的即时数据库。建立在 Neo4j 之上
数据库·typescript·neo4j
狂炫一碗大米饭13 小时前
如何在 TypeScript 中使用类型保护
typescript
@一枝梅16 小时前
vue3 vite.config.js 引入bem.scss文件报错
javascript·rust·vue·scss
码农之王18 小时前
(一)TypeScript概述和环境搭建
前端·后端·typescript
胡斌附体19 小时前
表单设计器拖拽对象时添加属性
vue·vuedraggable·draggable·clone的使用·遇到的问题
蚂小蚁21 小时前
从DeepSeek翻车案例看TypeScript类型体操的深层挑战
typescript·deepseek·trae
年老体衰按不动键盘1 天前
快速部署和启动Vue3项目
java·javascript·vue