封装一个返回一次性函数的钩子

131 阅读1分钟
import {Ref} from "vue";

type MaybeRef<T> = T | Ref<T>
export type UnrefFn<T> = T extends (...args: infer A) => infer R ? (...args: { [K in keyof A]: MaybeRef<A[K]> }) => R : never

/**
 * 它返回一个只会调用原始函数一次的函数
 * @param {T} fn - 要调用一次的函数
 * @returns {void} 一个只会被调用一次的函数
 */
export function useOnceFn<T extends Function>(fn: T) {
  let flag = true
  function onceFn(...args) {
    if (flag) {
      flag = false
      fn(...args)
    }
  }
  return onceFn as UnrefFn<T>
}

Demo

let count = $ref(0)

const increaseOnce = useOnceFn(() => {
  count++
  console.log(count)
})
setInterval(() => {
  increaseOnce() //只会打印一次
}, 1000)