Kliping
KlipingBerandaDokumentasiKomponenBlocksVariasiTemplateDice UIHooks
Memulai
  • Pengenalan
  • Instalasi
  • Kredit
State
  • useBoolean
  • useControllableValue
  • useCounter
  • useDebounce
  • useResetState
  • useThrottle
  • useToggle
Lanjutan
  • useCreation
  • useCustomCompareEffect
  • useLatest
  • useLockFn
  • useMemoizedFn
  • usePrevious
Siklus Hidup
  • useDebounceEffect
  • useDebounceFn
  • useDeepCompareEffect
  • useDeepCompareLayoutEffect
  • useEffectEvent
  • useEffectWithTarget
  • useInterval
  • useIsHydrated
  • useIsomorphicLayoutEffect
  • useMount
  • useThrottleEffect
  • useThrottleFn
  • useTimeout
  • useUnmount
  • useUpdate
  • useUpdateEffect
Peramban
  • useActiveElement
  • useBattery
  • useClickAnyWhere
  • useClickAway
  • useClipboard
  • useDocumentVisibility
  • useElementSize
  • useEventListener
  • useFps
  • useFullscreen
  • useHash
  • useHover
  • useInViewport
  • useIsMatchMedia
  • useIsOnline
  • useMouse
  • useNetwork
  • useOs
  • useScrollLock
  • useTextSelection
  • useTitle
Pengembangan
  • useWhyDidYouUpdate
Paket Luar
  • useMcp
  • useQuery
  • useStickToBottom
  • useSwr
Pustaka
  • isBrowser
  • createContext
  • bacaElemen
  • saatTerpasang

useMouse

SebelumnyaBerikutnya

Posisi penunjuk, dengan dukungan sentuh.

0 × 0

Sumber: belum ada · koordinat relatif jendela

type menentukan sistem koordinat yang dipakai, dan pilihannya berpengaruh:

  • page — relatif terhadap dokumen, ikut bergeser saat halaman digulung
  • client — relatif terhadap jendela, tidak terpengaruh gulungan
  • screen — relatif terhadap layar fisik
  • movement — selisih dari peristiwa sebelumnya, untuk pointer lock

sourceType menyebut dari mana angkanya datang. Itu yang membedakan "penunjuk di pojok kiri atas" dari "belum ada penunjuk sama sekali", yang kalau tidak dibedakan akan membuat efek ikut-kursor melompat ke sudut saat halaman baru dibuka.

Pemasangan ​

npx shadcn-vue@latest add @kliping/use-mouse

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

Ikut terpasang sendiri: use-event-listener.

Salin dulu is-browser, target, use-event-listener — masing-masing memuat sumbernya di halamannya sendiri — lalu tempel berkas ini.

ts
import { ref, toValue } from 'vue'
import type { MaybeRefOrGetter } from 'vue'
import { useEventListener } from '@/composables/use-event-listener'

export type JenisKoordinat = 'page' | 'client' | 'screen' | 'movement'
export type SumberPenunjuk = 'mouse' | 'touch' | null

export interface UseMouseOptions {
  /** Sistem koordinat. Bawaan: `page`. */
  type?: JenisKoordinat
  /** Ikuti peristiwa sentuh. Bawaan: true. */
  touch?: MaybeRefOrGetter<boolean>
  /** Kembalikan ke nilai awal saat sentuhan diangkat. Bawaan: false. */
  resetOnTouchEnds?: boolean
  initialValue?: { x: number, y: number }
}

const KUNCI_X = { page: 'pageX', client: 'clientX', screen: 'screenX', movement: 'movementX' } as const
const KUNCI_Y = { page: 'pageY', client: 'clientY', screen: 'screenY', movement: 'movementY' } as const

export function useMouse(options: UseMouseOptions = {}) {
  const {
    type = 'page',
    touch = true,
    resetOnTouchEnds = false,
    initialValue = { x: 0, y: 0 },
  } = options

  const x = ref(initialValue.x)
  const y = ref(initialValue.y)
  const sourceType = ref<SumberPenunjuk>(null)

  const dariTetikus = (peristiwa: MouseEvent) => {
    x.value = peristiwa[KUNCI_X[type]]
    y.value = peristiwa[KUNCI_Y[type]]
    sourceType.value = 'mouse'
  }

  const dariSentuhan = (peristiwa: TouchEvent) => {
    const titik = peristiwa.touches[0] ?? peristiwa.changedTouches[0]
    if (!titik)
      return

    // Sentuhan tidak punya `movementX`/`movementY`. Yang paling mendekati
    // maksudnya adalah koordinat jendela, jadi itu yang dipakai.
    if (type === 'movement') {
      x.value = titik.clientX
      y.value = titik.clientY
    }
    else {
      x.value = titik[KUNCI_X[type] as 'pageX' | 'clientX' | 'screenX']
      y.value = titik[KUNCI_Y[type] as 'pageY' | 'clientY' | 'screenY']
    }

    sourceType.value = 'touch'
  }

  const aktifSentuh = () => toValue(touch)

  useEventListener('mousemove', dariTetikus, { passive: true })
  useEventListener('dragover', dariTetikus, { passive: true })

  useEventListener('touchstart', dariSentuhan, { passive: true, enable: aktifSentuh })
  useEventListener('touchmove', dariSentuhan, { passive: true, enable: aktifSentuh })
  useEventListener('touchend', (peristiwa: TouchEvent) => {
    if (resetOnTouchEnds) {
      x.value = initialValue.x
      y.value = initialValue.y
      return
    }
    dariSentuhan(peristiwa)
  }, { passive: true, enable: aktifSentuh })

  return { x, y, sourceType }
}

API ​

ts
export type JenisKoordinat = 'page' | 'client' | 'screen' | 'movement'
export type SumberPenunjuk = 'mouse' | 'touch' | null

export interface UseMouseOptions {
  /** Sistem koordinat. Bawaan: `page`. */
  type?: JenisKoordinat
  /** Ikuti peristiwa sentuh. Bawaan: true. */
  touch?: MaybeRefOrGetter<boolean>
  /** Kembalikan ke nilai awal saat sentuhan diangkat. Bawaan: false. */
  resetOnTouchEnds?: boolean
  initialValue?: { x: number, y: number }
}

export function useMouse(options: UseMouseOptions = {})
useIsOnlineuseNetwork

Di halaman ini

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