vue のアンチリピートクリックのいくつかの実装


序文

プロジェクトの開発プロセス中に、手の速度が速い場合、vueコンポーネントのクリック イベントが連続して複数回トリガーされることが判明しました。この質問により、予期しない問題が生じる可能性がありますbug

以下にいくつかの解決策を示します。


1. js アンチシェイクと 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>

2. クリック状態を制御する

変数 (例: isLock) を定義してボタンのプロパティを制御しdisable、ユーザーが短時間にボタンを複数回クリックすることを防ぎます。

次のように進めます。

  • まず、ボタンをクリックできるように変数のisLock属性値を設定します ( )falsedisable: true
  • ユーザーがクリックすると、すぐにボタンをクリックできないように設定します ( disable: false)
  • イベントの実行または対応する間隔を待った後、ボタンをクリック可能な状態に戻します。

コードは次のとおりです(例)。

<el-button @click="clickBtn" :disable="isLock">按钮</el-button>
export default{
    
    
	data(){
    
    
		return {
    
    
			isLock: false, // 控制按钮的disable属性
		}
	},
	methods: {
    
    
		clickBtn(){
    
    
		 	// 设置按钮不可点击(disable: false)
			this.isLock = true
			// 执行耗时间的代码或事件请求等....
			
			// 等待事件执行完或者相应的间隔时间后,恢复按钮为可点击状态
			setTimeout(() => {
    
    
				this.isLock = false
			}, 2000)
		}
	}
}

3. デバウンス機能のみを使用する

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>


要約する

既存の問題

方法一方法三2つの方法の問題

方法一,方法三この 2 つの方法の中心となるロジックはdebounceアイデアを使用することですが、使用方法が異なります。

これら 2 つの方法は、基本的にクリックの繰り返しを防止するというニーズを満たすことができますが、実際のテストでは、遅延時間を制御するのが容易ではないことが判明しました。遅延時間が短く (<150ms)、素早いクリックでも複数のイベントがトリガーされる可能性があります。遅延時間が長い (>600 ミリ秒) 場合、ユーザーがクリックしてイベントをトリガーした後に明らかな遅延プロセスが発生し、ユーザー エクスペリエンスはあまり良くありません。

まず、達成したいことを定義しましょう。

  1. ユーザーがボタンを押すと、すぐにクリック イベントが発生します。
  2. ユーザーがボタンを素早く連続して押した場合、最初のクリック イベントのみがトリガーされます。
  3. ユーザーが中断することなく狂ったようにボタンをクリックすると (暴力的なテスト)、最初のイベントのみがすぐにトリガーされ、タイムアウト期間が経過しても、狂ったようにクリックしている間はイベントはトリガーされません。

解決

使用lodashdebounce;

コードは以下のように表示されます:

<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さらにこれら 2 つの属性に関する具体的な説明についてはdebouncelodash关键配置の公式ドキュメントを参照してくださいleadingtrailing

おすすめ

転載: blog.csdn.net/weixin_48353638/article/details/130201347