Vue中使用debounce防抖(ts)

一、抽象組件使用方式

1、封裝抽象組件(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
  }
})

2、組件使用方式

  • 引入全局組件

    首先需要將 debounce.js 文件在入口文件(main.ts)中全局引入。當然也可以按照需要修改 debounce.js 文件,按需引入。

import Vue from 'vue'
import App from './App.vue'
...
import '@/xxx/debounce'
  • 在模版中使用

    其中time爲必選參數。 event 和 immediate 參數都是可選參數。

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

    如果需要立即執行的話,可以將 immediate 參數設置爲 true。

<template>
  <div>
    <Debounce :time="500" :immediate="true" events="click,mousemove">
      <button @click="print(123)" @mousemove="print2(123)" style="width: 500px;height: 500px">點擊我</button>
    </Debounce>
  </div>
</template>

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'

@Component
export default class Test extends Vue {
  print(v: number) {
    console.log(v)
  }
  
  print2(v: number) {
    console.log(v)
  }
}
</script>

二、普通使用方式

1、安裝並引入 lodash 庫,直接使用。

<template>
  <div>
    <button
      @click="clickButton(123)"
      @mousemove="clickButton(123)"
      style="width:500px;height: 500px"
    >click me!</button>
  </div>
</template>

<script lang="ts">
import { Vue, Component } from 'vue-property-decorator'
import * as _ from 'lodash'

export default class Service extends Vue {
  private clickButton = _.debounce(this.print, 500, {
    leading: true,
    trailing: false
  })

  private print(v: number) {
    console.log(v)
  }
}
</script>

總結

兩種使用方式各有千秋,那麼你喜歡哪個呢?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章