Appearance
时序控制 useLockFn / useDebounceFn / useThrottleFn
业务侧最高频的三类时序问题各给一个最小 hook:防重复提交(useLockFn)、防抖(useDebounceFn,停顿才算数)、节流(useThrottleFn,高频按节奏放行)。零依赖、作用域销毁自动清理(防抖 / 节流)。
useLockFn:提交防重
执行期间(及可选反馈保持期)忽略后续调用,loading 直接绑定按钮——比手动 :loading 收敛在函数维度,多入口(按钮 + 回车)调用同一函数也只放行一次。
ts
const { run: submit, loading } = useLockFn(async (values) => {
await api.save(values)
ElMessage.success('已提交')
})
// 模板:<el-button :loading="loading" @click="submit(form)">提交</el-button>连点按钮或输入框内回车,1.5s 内只发一次。
已支付:¥0(连点不会多扣)
已完成:—;执行期间再次点击不会启动第二批。
已保存 0 次;接口 0.6s 即回,但按钮锁到 2.1s 才放开。
useDebounceFn:防抖(trailing)
最后一次调用后 delay ms 触发一次;cancel 取消等待、flush 立即触发等待中的值(「立即应用」按钮场景)。
ts
const { run: search, cancel, flush, pending } = useDebounceFn((kw: string) => {
void api.suggest(kw)
}, 400)请求 0 次(快速连续输入只在停顿后发 1 次)
价格 ≤ 100 元
已按 ≤100 元查询(共 0 次);flush 可不等停顿立即触发等待中的值。
useThrottleFn:节流(leading + trailing)
interval 内至多触发一次:首次立即响应,间隔内的末次参数在间隔尾补发(最后一次调用不丢)。
ts
const { run: onScroll } = useThrottleFn(() => {
if (nearBottom()) loadMore()
}, 500) 条目 1
条目 2
条目 3
条目 4
条目 5
条目 6
条目 7
条目 8
条目 9
条目 10
条目 11
条目 12
条目 13
条目 14
条目 15
条目 16
条目 17
条目 18
条目 19
条目 20
条目 21
条目 22
条目 23
条目 24
条目 25
条目 26
条目 27
条目 28
条目 29
条目 30
触发检查 0 次 / 加载 0 次(滚动到底部连续触发也被限到 500ms 一次)
窗口:0 × 0已按节流更新 0 次——拖拽浏览器窗口边缘试试。
API
useLockFn(fn, options?)
| 成员 | 类型 | 说明 |
|---|---|---|
| run | (...args) => Promise | undefined | 锁定期间调用返回 undefined(不排队不重入) |
| loading | Ref<boolean> | 执行中(含 lockDuring 保持期),绑定按钮 loading / disabled |
| 选项 | 类型 | 默认 | 说明 |
|---|---|---|---|
| lockDuring | number | 0 | 成功/失败后继续锁定 ms(反馈期防误触) |
useDebounceFn(fn, delay = 300)
| 成员 | 类型 | 说明 |
|---|---|---|
| run | (...args) => void | 停止调用 delay ms 后触发一次 |
| cancel | () => void | 取消未触发的等待 |
| flush | () => void | 立即触发等待中的调用(无等待不动作) |
| pending | () => boolean | 是否有待触发的等待 |
useThrottleFn(fn, interval = 300)
| 成员 | 类型 | 说明 |
|---|---|---|
| run | (...args) => void | 间隔内首次立即触发,末次参数间隔尾补发 |
| cancel | () => void | 取消待补发的末次调用 |
| pending | () => boolean | 是否处于节流间隔内 |
选型
- 会写库 / 会付钱 / 会发消息的动作 →
useLockFn(一次都不许多); - 等用户停(联想、联动查询、草稿保存)→
useDebounceFn; - 高频事件按节奏(scroll / resize / mousemove)→
useThrottleFn。