4.6 Sensors -- useMouse

4.6 Sensors – useMouse

https://vueuse.org/core/useMouse/

作用

响应式地返回鼠标位置

官方示例

import { useMouse } from '@vueuse/core'

const { x, y, sourceType } = useMouse()

参数type可以传入page、client、movement,分别代表:

  1. page:表示鼠标事件在页面上的 X 和 Y 坐标位置,它们包括了页面的滚动偏移。
  2. client:表示鼠标事件在视口中的 X 和 Y 坐标位置,它们不包括页面的滚动偏移
  3. movement:这两个属性表示自上一个鼠标事件以来鼠标在视口中的水平(X)和垂直(Y)移动量。
  • 无渲染组件代码如下:
<template>
  <UseMouse v-slot="{ x, y }">
    x: {{ x }}
    y: {{ y }}
  </UseMouse>
</template>

源码分析

主要逻辑是注册 mousemove、dragover、touchstart、touchmove、touchend事件,在移动中修改坐标值。

touch比较特殊,只有按下时才开始监听,且触摸点很多的话,只取第一个,主要是移动设备。

export function useMouse(options: UseMouseOptions = {}) {
  const {
    type = 'page',
    touch = true,
    resetOnTouchEnds = false, // touchEnd 时默认不清空数据
    initialValue = { x: 0, y: 0 },
    window = defaultWindow,
    eventFilter,
  } = options

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

  const mouseHandler = (event: MouseEvent) => {
    if (type === 'page') {
      x.value = event.pageX
      y.value = event.pageY
    }
    else if (type === 'client') {
      x.value = event.clientX
      y.value = event.clientY
    }
    else if (type === 'movement') {
      x.value = event.movementX
      y.value = event.movementY
    }
    sourceType.value = 'mouse'
  }
  const reset = () => {
    x.value = initialValue.x
    y.value = initialValue.y
  }
  
  const touchHandler = (event: TouchEvent) => {
    // 只有按下的时候才修改坐标,且以第一个接触点为准
    if (event.touches.length > 0) {
      const touch = event.touches[0]
      if (type === 'page') {
        x.value = touch.pageX
        y.value = touch.pageY
      }
      else if (type === 'client') {
        x.value = touch.clientX
        y.value = touch.clientY
      }
      sourceType.value = 'touch'
    }
  }

  const mouseHandlerWrapper = (event: MouseEvent) => {
    return eventFilter === undefined ? mouseHandler(event) : eventFilter(() => mouseHandler(event), {} as any)
  }

  const touchHandlerWrapper = (event: TouchEvent) => {
    return eventFilter === undefined ? touchHandler(event) : eventFilter(() => touchHandler(event), {} as any)
  }

  if (window) {
    useEventListener(window, 'mousemove', mouseHandlerWrapper, { passive: true })
    useEventListener(window, 'dragover', mouseHandlerWrapper, { passive: true })
    if (touch && type !== 'movement') {
      useEventListener(window, 'touchstart', touchHandlerWrapper, { passive: true })
      useEventListener(window, 'touchmove', touchHandlerWrapper, { passive: true })
      if (resetOnTouchEnds)
        useEventListener(window, 'touchend', reset, { passive: true })
    }
  }

  return {
    x,
    y,
    sourceType,
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值