【VueUse.js】——useMouse篇(包括useMouseinElement和useMousePressed)+新手专用

一、引言

        useMouse 是 VueUse 提供的一个功能,用于在 Vue.js 应用中跟踪鼠标位置。它会返回鼠标的 x 和 y 坐标,并可以配置处理触摸事件、滚动事件和自定义事件提取器。
        基本用法是导入 useMouse 并访问坐标。还可以通过选项禁用触摸跟踪或指定目标元素进行自定义。

二、引入

npm i @vueuse/core

三、揭秘useMouse

  1. 默认使用
<script>
    import {useMouse} from '@vueuse/core';
    const { x, y } = useMouse();
</script>

在这里插入图片描述
2. 使用touch选项

<script lang="ts" setup>
    import {ref,computed,watch,onMounted} from 'vue';
    import {useMouse } from '@vueuse/core';
    const {x,y} = useMouse({  // x,y就是鼠标位置
    	touch: false	// 不响应触摸事件
    });	
</script>

①touch为false:仅响应鼠标事件;
②touch为true(默认):同时响应鼠标和触摸事件,比如手指按下屏幕然后上下拖时会得到触摸位置,而“”“仅响应鼠标事件”只会监测点击位置。

3. 使用target和type选项

<script lang="ts" setup>
// 必备依赖
import { ref } from 'vue';
import { useParentElement, useMouse } from '@vueuse/core';
import type { UseMouseEventExtractor } from '@vueuse/core'	//

const red = ref(null);
const cursor = ref(null);
const parentEl = useParentElement(cursor);
// useParentElement()参数:
// 无参:什么都不传,默认父元素为最外层div;
// 有参:传一个元素,就会获取到该元素的父元素;
const extractor: UseMouseEventExtractor = event => {
    console.log("看看这是啥",event);
    return event instanceof Touch ? null : [event.offsetX, event.offsetY]
}
// 官网的extractor写法等价如下
// const extractor: UseMouseEventExtractor = event => {
//     return event instanceof Touch ? null : [event.offsetX, event.offsetY];
// };
const { x, y } = useMouse({
    target: parentEl,   //只响应鼠标在curosr的父元素内的位置
    type:extractor
});
</script>

在这里插入图片描述

控制台打印可以看到extractor的event就是鼠标对象,那么接下来就考的是js基本功了

在这里插入图片描述
红线标出区域,可以自定义:
screenX 和 screenY:相对于整个屏幕的位置,适用于需要跨屏幕或绝对屏幕坐标的情况;
clientX 和 clientY:相对于浏览器视口的位置,适用于网页中的用户交互,不考虑滚动;
offsetX 和 offsetY:相对于事件目标元素的位置,适用于需要知道事件发生在元素内部具体位置的情况;(问题:如果元素内部有很多子元素,那么鼠标移动到每一个子元素的区域时,offset的值都会是相较于该子元素的左上角的点进行偏移,具体你可以试一下)
pageX 和 pageY:相对于整个文档的位置,适用于需要考虑页面滚动的情况;

四、揭秘useMouselnElement

        以上属性均被export,import之后即是响应式的,来个小案例直观感受一下,基于elementX、elementY和isOutside;

demo:自定义指针小案例

<template>
    <div>
        
        <div ref="red" class="red">
            <div ref="cursor" class="curso"></div>
            <h1>鼠标位置X:{{ x }}Y:{{ y }}</h1>
        </div>
    </div>
</template>

<script lang="ts" setup>
    import {ref,computed,watch,onMounted} from 'vue';
    import {useMouseInElement } from '@vueuse/core';
    const red = ref(null);
    const cursor = ref(null);
    const {
    	elementX,
    	elementY,
    	isOutside
    } = useMouseInElement(red);
    const x = computed({
        get(){
            if(!isOutside.value){   // 不在外面,返回元素内鼠标的位置
                return Math.floor(elementX.value);
            }
            return 0;  // 代码缺陷,鼠标离开指定区域后只能归位0
            // 我想的解决方案是外边创建一个响应式位置锁positionLock,outX,outY。
            // 鼠标移出,位置锁生效,根据isOutside交叉记录elementX和elementY为之前的位置
        },
        set(val){
            elementX.value=val;
        }
    })
    const y = computed({
        get(){
            if(!isOutside.value){   // 不在外面,返回元素内鼠标的位置
                return Math.floor(elementY.value);
            }
            return 0;  // 代码缺陷,鼠标离开指定区域后只能归位0
        },
        set(val){
            elementY.value=val;
        }
    })
    let cursorElement = null;
    onMounted(()=>{
        cursorElement = cursor.value;
    })
    watch([x,y],()=>{
        cursorElement.style.left = x.value+'px';
        cursorElement.style.top = y.value+'px';
        // console.dir(cursorElement);
    })
    

</script>

<style scoped>
    div{
        position: relative;
        height: 100vh; 
    }
    .curso{
        position: absolute;
        width: 20px;
        height: 20px;
        border-radius: 50%;
        border: 1px solid darkblue;
        background-color: aqua;
    }
    .curso::after{
        position: absolute;
        content: " ";
        width: 10px;
        height: 20px;
        top:-80%;
        left: -8px;
        transform: rotate(-45deg);
        transform-origin: center center;
        clip-path: polygon(50% 0%, 0% 100%, 100% 100%);
        background-color: aqua;
        border: 1px solid darkblue;
    }
    .red{
        display: flex;
        justify-content: center;
        align-items: center;
        margin: 0 auto;
        min-width: 600px;
        width: 70%;
        height: 300px;
        background-color: antiquewhite;
    }
</style>

五、useMousePressed

        useMousePressed() 提供了一个响应式的布尔值,表示鼠标按钮是否被按下。

const options: MousePressedOptions = {
  touch: true,      // 监听触摸事件
  drag: true,       // 监听拖动事件
  capture: true,    // 使用事件捕获
  initialValue: false, // 初始值
  target: parentEl,   // 捕获点击的目标元素
};

// 使用 useMousePressed 组合式函数,传入自定义选项
const { 
	pressed: isPressed, 
	sourceType 
} = useMousePressed(options);
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ℋᙚᵐⁱᒻᵉ鲸落

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值