kliping.pro
  • Docs
  • Directory
  • Colors
  • Typeset
Hooks
  • State7
  • Advanced6
  • Lifecycle16
    • useDebounceEffect
    • useDebounceFn
    • useDeepCompareEffect
    • useDeepCompareLayoutEffect
    • useEffectEvent
    • useEffectWithTarget
    • useInterval
    • useIsHydrated
    • useIsomorphicLayoutEffect
    • useMount
    • useThrottleEffect
    • useThrottleFn
    • useTimeout
    • useUnmount
    • useUpdate
    • useUpdateEffect
  • Browser21
  • Development1
  • Third-Party4
  • Libraries4

useInterval

PreviousNext

Menjalankan sesuatu berulang kali, dengan jeda yang boleh berubah.

Bedanya dari setInterval telanjang ada tiga, dan ketiganya sering jadi sumber cacat: timernya ikut mati bersama scope, jedanya bisa diganti tanpa memasang ulang, dan null menghentikannya tanpa perlu cabang if di pemanggilnya.

delay berupa null atau angka negatif berarti berhenti. Itu yang membuat pola "jalan hanya saat tab terlihat" jadi satu baris:

ts
const terlihat = useDocumentVisibility()
useInterval(muatUlang, () => (terlihat.value === 'visible' ? 5000 : null))

Installation ​

pnpm dlx shadcn-vue@latest add @kliping/use-interval

Perlu @kliping terdaftar di components.json project Anda. Lihat cara menyiapkannya.

Ikut terpasang sendiri: is-browser.

Salin dulu is-browser — masing-masing memuat sumbernya di halamannya sendiri — lalu tempel berkas ini.

ts
import { getCurrentScope, onScopeDispose, readonly, ref, toValue, watch } from 'vue'
import type { MaybeRefOrGetter } from 'vue'
import { isBrowser } from '@/lib/is-browser'

export interface UseIntervalOptions {
  /** Run once immediately, before the first delay elapses. */
  immediate?: boolean
}

export function useInterval(
  fn: () => void,
  delay: MaybeRefOrGetter<number | null> = 1000,
  options: UseIntervalOptions = {},
) {
  const { immediate = false } = options

  const isActive = ref(false)
  let timer: ReturnType<typeof setInterval> | undefined

  const pause = () => {
    if (timer !== undefined) {
      clearInterval(timer)
      timer = undefined
    }
    isActive.value = false
  }

  const start = (interval: number) => {
    pause()
    if (!isBrowser) return
    if (immediate) fn()
    timer = setInterval(fn, interval)
    isActive.value = true
  }

  const resume = () => {
    const interval = toValue(delay)
    if (typeof interval === 'number' && interval >= 0) start(interval)
  }

  watch(
    () => toValue(delay),
    (interval) => {
      if (typeof interval !== 'number' || interval < 0) {
        pause()
        return
      }
      start(interval)
    },
    { immediate: true },
  )

  if (getCurrentScope()) onScopeDispose(pause)

  return { isActive: readonly(isActive), pause, resume }
}

API ​

ts
export interface UseIntervalOptions {
  /** Run once immediately, before the first delay elapses. */
  immediate?: boolean
}

export function useInterval(
  fn: () => void,
  delay: MaybeRefOrGetter<number | null> = 1000,
  options: UseIntervalOptions = {},
)
PrevioususeEffectWithTargetNext useIsHydrated

On This Page

InstallationAPI
Dirilis di bawah lisensi MIT. Ditulis ulang untuk Vue dari shadcn-vue, shadcn-ui-blocks, dan shadcn-hooks. Hak cipta © 2026 Kliping