美文网首页VUE
vue防重复点击的几种实现

vue防重复点击的几种实现

作者: 误入IT的人 | 来源:发表于2021-05-27 09:52 被阅读0次

    前言

    项目开发过程中发现,在手速快的情况下,vue的组件点击事件会被连续触发多次。这个问题会产生一些意想不到的bug。
    下面我们提供几种解决办法

    一、使用js 防抖配合vue自定义指令实现。

    vue组件代码

    <template>
     <div>
      <div v-debounce="search" style="width: 100px;height: 100px;background-color: yellow;">快速连续点击</div>
     </div>
    </template>
    <script>
     export default {
      name: 'debounce',
      data () {
       return {
        msg: 'Welcome to Your Vue.js App',
        text: '',
        count: 1
       }
      },
      directives: {
       debounce: {
        inserted: function (el, binding) {
          let timer
          el.addEventListener('click', () => {
          if (timer) {
           clearTimeout(timer)
          }
          timer = setTimeout(() => {
           binding.value()
          }, 300)
         })
        }
       }
      },
      methods: {
       search () {
       // 实际要进行的操作
        this.count++
        console.log('count is:' + this.count)
       }
      }
     }
    </script>
    
    二、只使用debounce函数

    定义common.js公共方法文件

    /**
     * 函数防抖
     */
    export function debounce(fn, delay) {
     // 记录上一次的延时器
     var timer = null;
     var delay = delay || 200;
     return function() {
      var args = arguments;
      var that = this;
      // 清除上一次延时器
      clearTimeout(timer)
      timer = setTimeout(function() {
        fn.apply(that,args)
      }, delay);
     }
    }
    

    vue组件引入common.js

    import {debounce} from '../common/common.js'
    

    vue组件代码

    <template>
        <div>
            <div @click="handleClick" style="width: 100px;height: 100px;background-color: yellow;">快速连续点击</div>
        </div>
    </template>
    
    <script>
        import {debounce,throttle} from '../common/common.js'
        export default{
            data() {
                return {
                    
                }
            },
            methods:{
                handleClick:debounce(function(){
                    console.log('业务逻辑')
                },300),
            }
        }
    </script>
    
    <style>
    </style>
    
    

    以上两种方式存在的问题
    以上两种方式实现的核心逻辑都是使用debounce的思想,只是使用方式上的不同。
    这两种方式已经基本上能满足防重复点击的需求,但实际测试发现延时的时间不好控,如果延时时间短(<150ms)快速点击还是会有几率多次触发事件。延时时间长(>600ms),用户点击后会有个明显的延时过程才能触发事件,用户体验就不太好。

    首先明确下我们想要实现的效果。

    1. 用户在按下按钮的时候立即触发点击事件。
    2. 用户在快速连续按下按钮的时候只触发第一次的点击事件。
    3. 用户不间断疯狂点击按钮(暴力测试),也只是立即触发第一次的事件,在疯狂点击的过程中不会触发事件,即使超时时间已经过去。

    三、最终解决方案 lodash

    哎呀,这库真香啊,官网地址奉上 lodash
    我们这里不展开分析这个库,只用这个库来实现防重复点击的需求。
    不多说直接上代码吧。

    安装lodash

    npm i --save lodash
    

    组件中引入

    import _ from "lodash"
    

    官方也是习惯将这个库命名为下划线,是不是很与众不同,可能是为了防重名吧,这里不多探讨。

    vue组件完整实现

    <template>
        <div>
            <div @click="handleClick" style="width: 100px;height: 100px;background-color: yellow;">快速连续点击</div>
        </div>
    </template>
    
    <script>
        import _ from "lodash"
        export default {
            methods: {
                handleClick:_.debounce(function() {
                    //你的业务逻辑
                    console.log('执行业务逻辑1 ' + Math.random())
                }, 1000, {
                    'leading': true, //在延迟开始前立即调用事件
                    'trailing': false, //在延时结束后不调用,保证事件只被触发一次
                })
            }
        }
    </script>
    <style>
    </style>
    
    

    lodash的debounce的关键配置就是 leading trailing
    关于这两个属性的具体解释可以参照lodash官方文档。

    相关文章

      网友评论

        本文标题:vue防重复点击的几种实现

        本文链接:https://www.haomeiwen.com/subject/utvksltx.html