diff --git a/packages/shared/useDebounceFn/index.md b/packages/shared/useDebounceFn/index.md
index f18a5e85e4c7..19357ffad79c 100644
--- a/packages/shared/useDebounceFn/index.md
+++ b/packages/shared/useDebounceFn/index.md
@@ -17,7 +17,7 @@ const debouncedFn = useDebounceFn(() => {
// do something
}, 1000)
-document.addEventLisenter('resize', debouncedFn)
+document.addEventListener('resize', debouncedFn)
```
## Related Functions
diff --git a/packages/shared/useThrottle/demo.vue b/packages/shared/useThrottle/demo.vue
index f71f799b1513..58ac7e1af1aa 100644
--- a/packages/shared/useThrottle/demo.vue
+++ b/packages/shared/useThrottle/demo.vue
@@ -3,8 +3,9 @@ import { ref, watch } from 'vue-demi'
import { useThrottle } from '.'
const trailing = ref(true)
+const leading = ref(false)
const input = ref('')
-const throttled = useThrottle(input, 1000, trailing.value)
+const throttled = useThrottle(input, 1000, trailing.value, leading.value)
const updated = ref(0)
watch(throttled, () => {
@@ -20,5 +21,6 @@ watch(throttled, () => {
Throttled: {{ throttled }}
Times Updated: {{ updated }}
Trailing: {{ trailing }}
+ Leading: {{ leading }}
diff --git a/packages/shared/useThrottle/index.md b/packages/shared/useThrottle/index.md
index 3a1738e7cd02..52834ca1a5ef 100644
--- a/packages/shared/useThrottle/index.md
+++ b/packages/shared/useThrottle/index.md
@@ -26,6 +26,16 @@ const input = ref('')
const throttled = useThrottle(input, 1000, false)
```
+### Leading
+
+Allows the callback to be invoked immediately (on the leading edge of the `ms` timeout). If you don't want this begavior, set 4rd param `false` (it's `true` by default):
+
+```js
+import { useThrottle } from '@vueuse/core'
+
+const input = ref('')
+const throttled = useThrottle(input, 1000, undefined, false)
+```
## Related Functions
diff --git a/packages/shared/useThrottle/index.ts b/packages/shared/useThrottle/index.ts
index d162374cb134..b76ea18f2a09 100644
--- a/packages/shared/useThrottle/index.ts
+++ b/packages/shared/useThrottle/index.ts
@@ -8,8 +8,9 @@ import { useThrottleFn } from '../useThrottleFn'
* @param value Ref value to be watched with throttle effect
* @param delay A zero-or-greater delay in milliseconds. For event callbacks, values around 100 or 250 (or even higher) are most useful.
* @param [trailing=true] if true, update the value again after the delay time is up
+ * @param [leading=true] if true, update the value on the leading edge of the ms timeout
*/
-export function useThrottle(value: Ref, delay = 200, trailing = true) {
+export function useThrottle(value: Ref, delay = 200, trailing = true, leading = true) {
if (delay <= 0)
return value
@@ -17,7 +18,7 @@ export function useThrottle(value: Ref, delay = 200, trailing = true) {
const updater = useThrottleFn(() => {
throttled.value = value.value
- }, delay, trailing)
+ }, delay, trailing, leading)
watch(value, () => updater())
diff --git a/packages/shared/useThrottleFn/index.md b/packages/shared/useThrottleFn/index.md
index e00d906cdaf3..80c1c2f0e57f 100644
--- a/packages/shared/useThrottleFn/index.md
+++ b/packages/shared/useThrottleFn/index.md
@@ -17,7 +17,7 @@ const throttledFn = useThrottleFn(() => {
// do something, it will be called at most 1 time per second
}, 1000)
-document.addEventLisenter('resize', throttledFn)
+document.addEventListener('resize', throttledFn)
```
## Related Functions
diff --git a/packages/shared/useThrottleFn/index.ts b/packages/shared/useThrottleFn/index.ts
index 877d51a6032b..98189b54db07 100644
--- a/packages/shared/useThrottleFn/index.ts
+++ b/packages/shared/useThrottleFn/index.ts
@@ -10,11 +10,13 @@ import { createFilterWrapper, FunctionArgs, throttleFilter, MaybeRef } from '../
*
* @param [trailing=true] if true, call fn again after the time is up
*
+ * @param [leading=true] if true, call fn on the leading edge of the ms timeout
+ *
* @return A new, throttled, function.
*/
-export function useThrottleFn(fn: T, ms: MaybeRef = 200, trailing = true): T {
+export function useThrottleFn(fn: T, ms: MaybeRef = 200, trailing = true, leading = true): T {
return createFilterWrapper(
- throttleFilter(ms, trailing),
+ throttleFilter(ms, trailing, leading),
fn,
)
}
diff --git a/packages/shared/utils/filters.ts b/packages/shared/utils/filters.ts
index 79c9f19815f1..6a6e48cb8204 100644
--- a/packages/shared/utils/filters.ts
+++ b/packages/shared/utils/filters.ts
@@ -66,10 +66,12 @@ export function debounceFilter(ms: MaybeRef) {
*
* @param ms
* @param [trailing=true]
+ * @param [leading=true]
*/
-export function throttleFilter(ms: MaybeRef, trailing = true) {
+export function throttleFilter(ms: MaybeRef, trailing = true, leading = true) {
let lastExec = 0
let timer: ReturnType | undefined
+ let preventLeading = !leading
const clear = () => {
if (timer) {
@@ -91,15 +93,19 @@ export function throttleFilter(ms: MaybeRef, trailing = true) {
if (elapsed > duration) {
lastExec = Date.now()
- invoke()
+ if (preventLeading) preventLeading = false
+ else invoke()
}
else if (trailing) {
timer = setTimeout(() => {
lastExec = Date.now()
+ if (!leading) preventLeading = true
clear()
invoke()
}, duration)
}
+
+ if (!leading && !timer) timer = setTimeout(() => preventLeading = true, duration)
}
return filter