VueUse中常用的传感器函数

onClickOutside

监听元素外部的点击。对于模式或下拉菜单很有用。

常见于点击弹窗蒙层关闭,点击元素外部触发事件。

用法:

<script setup>
import { ref } from 'vue'
import { onClickOutside } from '@vueuse/core'

const target = ref(null)

onClickOutside(target, event => console.log(event))
</script>

<template>
  <div ref="target">
    Hello world
  </div>
  <div>Outside element</div>
</template>

onKeyStroke

可以监听键盘按下指定键的事件。

import { onKeyStroke } from '@vueuse/core'

onKeyStroke('ArrowDown', (e) => {
  e.preventDefault()
})

聆听多个键

import { onKeyStroke } from '@vueuse/core'

onKeyStroke(['s', 'S', 'ArrowDown'], (e) => {
  e.preventDefault()
})

// listen to all keys by [true / skip the keyDefine]
onKeyStroke(true, (e) => {
  e.preventDefault()
})
onKeyStroke((e) => {
  e.preventDefault()
})

自定义事件目标

onKeyStroke('A', (e) => {
  console.log('Key A pressed on document')
}, { target: document })

忽略重复事件

import { onKeyStroke } from '@vueuse/core'

// use `autoRepeat` option
onKeyStroke('A', (e) => {
  console.log('Key A pressed')
}, { dedupe: true })

自定义键盘事件

onKeyStroke('Shift', (e) => {
  console.log('Shift key up')
}, { eventName: 'keyup' })

//或
onKeyUp('Shift', () => console.log('Shift key up'))

useElementHover

元素是否处于hover状态(反应性元素的悬停状态)。

在hover时展示不同的文字状态等可以用到

<script setup lang="ts">
import { ref } from 'vue'
import { useElementHover } from '@vueuse/core'

const el = ref<HTMLButtonElement>()
const isHovered = useElementHover(el, { delayEnter: 200, delayLeave: 600 })
</script>

<template>
  <button ref="el">
    <span>{{ isHovered ? 'Thank you!' : 'Hover me' }}</span>
  </button>
</template>

useIdle

跟踪用户是否处于非活动状态。

在鼠标键盘不动的情况下,即处于非活动状态。

import { useIdle } from '@vueuse/core'

// 空闲时间达到5min后,idle.value为true
const { idle, lastActive } = useIdle(5 * 60 * 1000) 

console.log(idle.value) // true or false
import { watch } from 'vue'
import { useCounter, useIdle } from '@vueuse/core'

const { inc, count } = useCounter()

const { idle, lastActive, reset } = useIdle(5 * 60 * 1000) // 5 min

watch(idle, (idleValue) => {
  if (idleValue) {
    inc()
    console.log(`Triggered ${count.value} times`)
    reset() // restarts the idle timer. Does not change lastActive value
  }
})

组件使用

<template>
  <UseIdle v-slot="{ idle }" :timeout="5 * 60 * 1000">
    Is Idle: {{ idle }}
  </UseIdle>
</template>

useMouse

反应性鼠标位置,用于获取鼠标x/y坐标和sourceType(mouse|touch)

import { useMouse } from '@vueuse/core'

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

默认情况下启用触摸。要仅检测鼠标更改,请将 touch 设置为 falsedragover 事件用于在拖动时跟踪鼠标位置。

const { x, y } = useMouse({ touch: false })

定制提取器

还可以提供自定义提取器函数来从事件中获取位置。

import type { UseMouseEventExtractor } from '@vueuse/core'
import { useMouse, useParentElement } from '@vueuse/core'

const parentEl = useParentElement()

const extractor: UseMouseEventExtractor = event => (
  event instanceof Touch
    ? null
    : [event.offsetX, event.offsetY]
)

const { x, y, sourceType } = useMouse({ target: parentEl, type: extractor })

组件使用

<template>
  <UseMouse v-slot="{ x, y }">
    x: {{ x }}
    y: {{ y }}
  </UseMouse>
</template>
<script setup lang="ts">
import { reactive } from 'vue'
import { stringify } from '@vueuse/docs-utils'
import { useMouse, useParentElement } from '@vueuse/core'
import type { UseMouseEventExtractor } from '@vueuse/core'

const parentEl = useParentElement()

const mouseDefault = reactive(useMouse())
const textDefault = stringify(mouseDefault)

const extractor: UseMouseEventExtractor = (event) => {
  if (typeof Touch !== 'undefined' && event instanceof Touch)
    return null
  else
    return [event.offsetX, event.offsetY]
}

const mouseWithExtractor = reactive(useMouse({ target: parentEl, type: extractor }))
const textWithExtractor = stringify(mouseWithExtractor)
</script>

<template>
  <p>Basic Usage</p>
  <pre lang="yaml">{{ textDefault }}</pre>
  <p>Extractor Usage</p>
  <pre lang="yaml">{{ textWithExtractor }}</pre>
</template>

usePointerSwipe

基于 PointerEvents 的反应式滑动检测, 鼠标拖动。

拖动元素时,触发回调事件

<script setup>
import { ref } from 'vue'
import { usePointerSwipe } from '@vueuse/core'

const el = ref(null)
const { isSwiping, direction } = usePointerSwipe(el)
</script>

<template>
  <div ref="el">
    Swipe here
  </div>
</template>
const container = ref(null);

const { distanceX, isSwiping } = usePointerSwipe(container, {
    onSwipe() {
       console.log('onswipe');
    },
    onSwipeEnd() {
       console.log('onend');
    },
});
effect(() => {
    console.log(isSwiping, distanceX);
});
<script setup lang="ts">
import { computed, ref } from 'vue'
import { usePointerSwipe } from '@vueuse/core'
import type { UseSwipeDirection } from '@vueuse/core'

const target = ref<HTMLElement | null>(null)
const container = ref<HTMLElement | null>(null)

const containerWidth = computed(() => container.value?.offsetWidth)

const left = ref('0')
const opacity = ref(1)

function reset() {
  left.value = '0'
  opacity.value = 1
}

const { distanceX, isSwiping } = usePointerSwipe(target, {
  disableTextSelect: true,
  onSwipe(e: PointerEvent) {
    if (containerWidth.value) {
      if (distanceX.value < 0) {
        const distance = Math.abs(distanceX.value)
        left.value = `${distance}px`
        opacity.value = 1.25 - distance / containerWidth.value
      }
      else {
        left.value = '0'
        opacity.value = 1
      }
    }
  },
  onSwipeEnd(e: PointerEvent, direction: UseSwipeDirection) {
    if (distanceX.value < 0 && containerWidth.value && (Math.abs(distanceX.value) / containerWidth.value) >= 0.5) {
      left.value = '100%'
      opacity.value = 0
    }
    else {
      left.value = '0'
      opacity.value = 1
    }
  },
})
</script>

<template>
  <div ref="container" class="bg-gray-200 rounded relative w-full h-[80px] m-auto flex items-center justify-center overflow-hidden">
    <button @click="reset">
      Reset
    </button>
    <div
      ref="target"
      class="absolute w-full h-full top-0 left-0 bg-[#3eaf7c] flex items-center justify-center"
      :class="{ 'transition-all duration-200 ease-linear': !isSwiping }"
      :style="{ left, opacity }"
    >
      <p class="flex text-white items-center">
        Swipe <mdi-arrow-right />
      </p>
    </div>
  </div>
</template>

useScroll

反应式滚动位置和状态。

鼠标滚动信息。

<script setup lang="ts">
import { useScroll } from '@vueuse/core'

const el = ref<HTMLElement | null>(null)
const { x, y, isScrolling, arrivedState, directions } = useScroll(el)
</script>

<template>
  <div ref="el" />
</template>

带偏移量

const { x, y, isScrolling, arrivedState, directions } = useScroll(el, {
  offset: { top: 30, bottom: 30, right: 30, left: 30 },
})

设置滚动位置

<script setup lang="ts">
import { useScroll } from '@vueuse/core'

const el = ref<HTMLElement | null>(null)
const { x, y } = useScroll(el)
</script>

<template>
  <div ref="el" />
  <button @click="x += 10">
    Scroll right 10px
  </button>
  <button @click="y += 10">
    Scroll down 10px
  </button>
</template>

平滑滚动

设置 behavior: smooth 以启用平滑滚动。behavior 选项默认为 auto,这意味着不平滑滚动。有关详细信息,请参阅 window.scrollTo() 上的 behavior 选项。

import { useScroll } from '@vueuse/core'

const el = ref<HTMLElement | null>(null)
const { x, y } = useScroll(el, { behavior: 'smooth' })

// Or as a `ref`:
const smooth = ref(false)
const behavior = computed(() => smooth.value ? 'smooth' : 'auto')
const { x, y } = useScroll(el, { behavior })

指令用法

<script setup lang="ts">
import type { UseScrollReturn } from '@vueuse/core'
import { vScroll } from '@vueuse/components'

const data = ref([1, 2, 3, 4, 5, 6])

function onScroll(state: UseScrollReturn) {
  console.log(state) // {x, y, isScrolling, arrivedState, directions}
}
</script>

<template>
  <div v-scroll="onScroll">
    <div v-for="item in data" :key="item">
      {{ item }}
    </div>
  </div>

  <!-- with options -->
  <div v-scroll="[onScroll, { throttle: 10 }]">
    <div v-for="item in data" :key="item">
      {{ item }}
    </div>
  </div>
</template>

useScrollLock

锁定元素的滚动。

<script setup lang="ts">
import { useScrollLock } from '@vueuse/core'

const el = ref<HTMLElement | null>(null)
const isLocked = useScrollLock(el)

isLocked.value = true // lock
isLocked.value = false // unlock
</script>

<template>
  <div ref="el" />
</template>

指令用法

<script setup lang="ts">
import { vScrollLock } from '@vueuse/components'
const data = ref([1, 2, 3, 4, 5, 6])
const isLocked = ref(false)
const toggleLock = useToggle(isLocked)
</script>

<template>
  <div v-scroll-lock="isLocked">
    <div v-for="item in data" :key="item">
      {{ item }}
    </div>
  </div>
  <button @click="toggleLock()">
    Toggle lock state
  </button>
</template>

useSwipe

基于 TouchEvents 的反应式滑动检测(touch事件滚动)。

使用同usePointerSwipe,不同的是一个是pc端,一个是移动端的事件。

<script setup>
const el = ref(null)
const { isSwiping, direction } = useSwipe(el)
</script>

<template>
  <div ref="el">
    Swipe here
  </div>
</template>

useTextSelection

基于 Window.getSelection 反应式跟踪用户文本选择。

文本选择相关数据

<script setup lang="ts">
import { useTextSelection } from '@vueuse/core'
const state = useTextSelection()
</script>

<template>
  <p>{{ state.text }}</p>
</template>

文字内容,宽高,以及距离页面上下左右距离。

export declare function useTextSelection(
  element?: MaybeRef<HTMLElement | Document | null | undefined>
): Ref<{
  text: string
  readonly height: number
  readonly width: number
  readonly left: number
  readonly right: number
  readonly top: number
  readonly bottom: number
}>
<script setup lang="ts">
import { computed, ref } from 'vue'
import { useTextSelection } from '@vueuse/core'

const demo = ref()
const { rects, text } = useTextSelection()
const selectedStyle = computed(() => text.value ? 'text-primary' : 'text-gray-400')
</script>

<template>
  <div ref="demo">
    <p class="font-600 text-blue-600">
      You can select any text on the page.
    </p>
    <p>
      <strong>Selected Text:</strong>
      <em
        :class="selectedStyle"
        class="whitespace-pre h-44 overflow-y-auto block"
      >{{ text || 'No selected' }}</em>
    </p>
    <p>
      <strong>Selected rects:</strong>
      <pre class="h-72" lang="json">{{ rects }}</pre>
    </p>
  </div>
</template>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值