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
,分别代表:
- page:表示鼠标事件在页面上的 X 和 Y 坐标位置,它们包括了页面的滚动偏移。
- client:表示鼠标事件在视口中的 X 和 Y 坐标位置,它们不包括页面的滚动偏移
- 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,
}
}