vue防止重复提交

438 阅读1分钟

频繁触发的事件如scroll,输入框input的change事件,本文介绍的click事件频繁点击都会高频率的触发,核心的方案是在事件触发后添加节流和防抖。

1、此类问题,都可以使用第三方库lodash中的debounce和throttle节流方式处理,两者之间的区别可以查看相关的文档。使用前用npm或者yarn安装下依赖

import debounce from "lodash.debounce"
let fn = debounce(()=>{console.log(1)},100)
//or
import throttle from "lodash.throttle"
let fn = throttle(()=>{console.log(22)},100)

上面的fn可以再执行高频操作的时候调用

2、基于vue的directive的实现方式,可以实现一个全局命令, 2.1 基于button按钮的方式,全局注册一个preventClick命令

//preventClick.js
export default (Vue)=>{
   Vue.directive('preventClick', {
     inserted (el) {
         el.addEventListener('click', () => {
           if (!el.disabled) {
             el.disabled = true
             setTimeout(() => {
               el.disabled = false
             }, 500)
           }
         })
       }
     })
   }
//mian.js,引入并使用
import preventClick from 'preventClick.js'
Vue.use(preventClick)

//*.vue 文件使用
<button @click='fn' v-preventClick></button>

2.2 任意元素的点击拦截,使用范围更广

//preventReClick。js
const preventReClick = (Vue) => {
  Vue.directive('preventReClick', {
    inserted(el, binding) {
      let timer;
      el.addEventListener('click', () => {
        if (timer) {
          clearTimeout(timer);
        }
        timer = setTimeout(() => {
          binding.value();
        }, 300);
      });
    },
  });
};

export default preventReClick;

 //mian.js,引入并使用
  import preventClick from 'preventClick.js'
  Vue.use(preventClick)
  
 
  //*.vue 文件使用
  <button v-preventClick='fn'></button>

3、vue项目全局拦截

const on = Vue.prototype.$on
// 防抖处理
Vue.prototype.$on = function (event, func) {
  let timer
  let newFunc = func
  if (event === 'click') {
    newFunc = function () {
      clearTimeout(timer)
      timer = setTimeout(function () {
        func.apply(this, arguments)
      }, 500)
    }
  }
  on.call(this, event, newFunc)
}

const on = Vue.prototype.$on
  
****// 节流****

```css
Vue.prototype.$on = function (event, func) {
  let previous = 0
  let newFunc = func
  if (event === 'click') {
    newFunc = function () {
      const now = new Date().getTime()
      if (previous + 1000 <= now) {
        func.apply(this, arguments)
        previous = now
      }
    }
  }
  on.call(this, event, newFunc)
}

blog.csdn.net/wuxiaoqing_…