Skip to content

v-throttle

对事件处理函数进行节流,限制执行频率。

起始版本: 1.0.0

用法

基本用法

vue
<template>
  <!-- 默认: 300ms -->
  <button v-throttle="handleClick">点击我</button>
</template>

<script setup>
function handleClick() {
  console.log('节流点击')
}
</script>

使用修饰符

vue
<template>
  <!-- 500ms 节流 -->
  <button v-throttle:500ms="handleClick">点击我</button>

  <!-- 1秒 节流 -->
  <button v-throttle:1s="handleClick">点击我</button>
</template>

带配置选项

vue
<template>
  <button v-throttle="{
    handler: handleClick,
    wait: 1000,
    leading: true,
    trailing: false
  }">
    点击我
  </button>
</template>

API

类型定义

typescript
interface ThrottleOptions {
  /** 需要节流的函数 */
  handler: (event: Event) => void
  /** 等待时间(毫秒) */
  wait?: number
  /** 是否在开始边界触发 */
  leading?: boolean
  /** 是否在结束边界触发 */
  trailing?: boolean
}

type ThrottleBinding = ThrottleOptions['handler'] | ThrottleOptions

选项

选项类型默认值描述
handlerFunction-需要节流的函数
waitnumber300等待时间(毫秒)
leadingbooleantrue是否在开始边界触发
trailingbooleantrue是否在结束边界触发

Composable 用法

你也可以使用 useThrottle composable 来实现相同功能:

vue
<script setup>
import { ref } from 'vue'
import { useThrottle } from 'directix'

const { run: throttledScroll, cancel } = useThrottle({
  handler: (event) => {
    console.log('滚动位置:', event.target.scrollTop)
  },
  wait: 100
})

// 在模板中使用
// <div @scroll="throttledScroll($event)">...</div>
</script>

API

typescript
interface UseThrottleOptions<T extends (...args: any[]) => any> {
  /** 需要节流的函数 */
  handler: T
  /** 等待时间(毫秒) */
  wait?: number | Ref<number>
  /** 是否在开始边界触发 */
  leading?: boolean | Ref<boolean>
  /** 是否在结束边界触发 */
  trailing?: boolean | Ref<boolean>
}

interface UseThrottleReturn<T> {
  /** 执行节流函数 */
  run: (...args: Parameters<T>) => void
  /** 取消待执行的函数 */
  cancel: () => void
}

示例

按钮点击

vue
<template>
  <button v-throttle:1s="saveData">
    保存(每秒最多点击一次)
  </button>
</template>

<script setup>
async function saveData() {
  console.log('保存中...')
  // 此处进行 API 调用
}
</script>

滚动处理

vue
<template>
  <div v-throttle:100ms="handleScroll" class="scroll-container">
    <!-- 内容 -->
  </div>
</template>

<script setup>
function handleScroll(event) {
  const scrollTop = event.target.scrollTop
  console.log('滚动位置:', scrollTop)
}
</script>

窗口大小调整

vue
<template>
  <div v-throttle:200ms="handleResize">
    窗口宽度: {{ width }}px
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

const width = ref(window.innerWidth)

function handleResize() {
  width.value = window.innerWidth
}

onMounted(() => {
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
})
</script>

鼠标移动追踪

vue
<template>
  <div
    v-throttle:50ms="handleMouseMove"
    class="tracking-area"
    @mousemove="handleMouseMove"
  >
    鼠标位置: {{ x }}, {{ y }}
  </div>
</template>

<script setup>
import { ref } from 'vue'

const x = ref(0)
const y = ref(0)

function handleMouseMove(event) {
  x.value = event.clientX
  y.value = event.clientY
}
</script>

基于 MIT 许可发布