1. 程式人生 > 程式設計 >在vue中使用防抖函式元件操作

在vue中使用防抖函式元件操作

初級

1、先寫好防抖函式

/**
 * @desc 防抖函式
 * @param {需要防抖的函式} func
 * @param {延遲時間} wait
 * @param {是否立即執行} immediate
 */
export function debounce(func,wait,immediate) {
 let timeout
 
 return function(...args) {
 let context = this
 if (timeout) clearTimeout(timeout)

 if (immediate) {
 let callNow = !timeout
 timeout = setTimeout(function() {
 timeout = null
 },wait)
 if (callNow) func.apply(context,args)
 } else {
 timeout = setTimeout(function() {
 func.apply(context,args)
 },wait)
 }
 }
}

2、然後在要使用的元件裡 import 進來

import { debounce } from 'xxx'

export default {
 data: {
 return {
 vm: this
 }
 },methods: {
 toDoSth: debounce((vm) => {
 // 這裡將當前元件例項當引數傳入
 // 就可以使用例項中定義的一些屬性、方法
 // 補充一下,這裡如果換成非箭頭函式的寫法,也可以直接訪問例項。
 },500,true
 )
 }
}

3、在元件方法中使用

template:

<div @click="toDoSth(vm)"></div>

高階

雖然上面的寫法已經能解決問題了,但是總覺得不夠美觀。

在網上搜索一番,看到有個哥們將防抖封裝成一個元件,果然和我想的一樣。不過這哥們直接將上下文當引數傳進來了,比我把整個例項傳進來高明,我在這個基礎上添加了 immediate 的功能,還有添加了預設不傳 event 引數的情況處理。

debounce.js 檔案:

import Vue from 'vue'

const debounce = (func,time,ctx,immediate) => {
 let timer
 const rtn = (...params) => {
 clearTimeout(timer)

 if (immediate) {
 let callNow = !timer
 timer = setTimeout(() => {
 timer = null
 },time)
 if (callNow) func.apply(ctx,params)
 } else {
 timer = setTimeout(() => {
 func.apply(ctx,params)
 },time)
 }
 }
 return rtn
}

Vue.component('Debounce',{
 abstract: true,props: ['time','events','immediate'],created() {
 this.eventKeys = this.events && this.events.split(',')
 },render() {
 const vnode = this.$slots.default[0]
 
 // 如果預設沒有傳 events,則對所有繫結事件加上防抖
 if (!this.eventKeys) {
 this.eventKeys = Object.keys(vnode.data.on)
 }
 
 this.eventKeys.forEach(key => {
 vnode.data.on[key] = debounce(
 vnode.data.on[key],this.time,vnode,this.immediate
 )
 })

 return vnode
 }
})

使用方式:

1、引入 debounce.js 檔案

import 'xxx/debounce.js'

export default {
 methods: {
 toDoSth(e) {
 // 這裡正常寫就可以了
 }
 }
}

2、在模版裡使用

其中time為必選引數。 event 和 immediate 引數都是可選引數。

如果元件下有多個事件繫結,那麼 event 可以自定義需要進行防抖處理的事件。

如果需要立即執行的話,可以將 immediate 引數設定為 true。

<Debounce :time="500" event="click" :immediate="true">
 <button @click="toDoSth($event,1)">click me</button>
</Debounce>

到此就完成了一次 Debounce 元件的封裝。

補充知識:vue防抖函式,避免暴力點選

1.vue專案/src/components/directive/clickAgain.js

import Vue from 'vue'

const clickAgain = Vue.directive('clickAgain',{
 // 指令的定義
 bind(el,binding,oldVnode) {
  // 繫結this
  let self = vnode.context;
  el.onclick = function (e) {
   if (self._is_click) {
    return false;
   }
   /*執行指令繫結的事件*/
   self[binding.expression]()
   self._is_click=true;
   setTimeout(()=>{
    self._is_click=false;
   },2000)

  };
 }
});
export default clickAgain

2.在main.js 引入

import clickAgain from './components/directive/clickAgain.js'

/* 引入避免暴力雙擊點選*/

Vue.use(clickAgain);

3.使用

<a-button key="submit" type="primary" :loading="false" v-clickAgain="handleOk">
 儲存
</a-button>

以上這篇在vue中使用防抖函式元件操作就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支援我們。