VueUse Gesture
@vueuse/gesture is a comprehensive collection of Vue Composables designed to provide robust and interactive gesture support for Vue applications. It offers a suite of hooks for various pointer and touch gestures, including `useDrag`, `useMove`, `useHover`, `useScroll`, `useWheel`, `usePinch`, and a generic `useGesture` for handling multiple interactions simultaneously. The library is currently stable at version `2.0.0` (last published approximately two years ago) and is an active part of the broader VueUse ecosystem. Its key differentiators include seamless compatibility with both Vue 2 and Vue 3 environments via `vue-demi`, offering both composable function-based and directive-based (e.g., `v-drag`) APIs. It is a direct port of the well-known `react-use-gesture` library, bringing similar declarative and powerful animation possibilities to the Vue ecosystem, and is explicitly designed to integrate smoothly with animation libraries like `@vueuse/motion`.
Common errors
-
Failed to resolve import "vue-use-gesture" from "src/components/MyComponent.vue". Does the file exist?
cause Attempting to import from the old, unmaintained package name `vue-use-gesture`.fixChange the import path to `@vueuse/gesture`: `import { useDrag } from '@vueuse/gesture'`. -
[Vue warn]: Failed to resolve component: v-drag If this is a custom element, make sure to add it to GlobalComponents property.
cause The `v-drag` directive was used without being registered with the Vue application.fixGlobally register the `DragDirective` at your app's entry point: `import { DragDirective } from '@vueuse/gesture'; app.directive('drag', DragDirective);`. -
[Vue warn]: inject() can only be used inside setup() or functional components.
cause Attempting to use `@vueuse/gesture` composables in a Vue 2 project without installing `@vue/composition-api`, or using them outside a `setup` function context.fixFor Vue 2, ensure `@vue/composition-api` is installed and registered. Ensure all `use*` hooks are called directly within the `setup` function of a component.
Warnings
- breaking The original `vue-use-gesture` package by koca has been superseded and re-homed under the VueUse organization as `@vueuse/gesture`. Ensure you are installing and importing from the `@vueuse/gesture` package.
- gotcha When creating draggable elements, it is crucial to set the `touch-action` CSS property to `none` (or specific axes like `pan-x`, `pan-y`) on the draggable element. Failing to do so can cause conflicts with native browser scrolling on touch devices, leading to unexpected behavior or glitches.
- gotcha For Vue 2 projects, `@vueuse/gesture` requires `@vue/composition-api` to be installed and correctly set up for the composables to function.
- gotcha If you intend to use the gesture directives (e.g., `v-drag`, `v-pinch`), they must be explicitly registered either globally via `app.directive()` (Vue 3) or `Vue.directive()` (Vue 2), or locally within components.
Install
-
npm install vue-use-gesture -
yarn add vue-use-gesture -
pnpm add vue-use-gesture
Imports
- useDrag
import { useDrag } from 'vue-use-gesture'import { useDrag } from '@vueuse/gesture' - useGesture
import { useGesture } from '@vueuse/gesture' - v-drag (directive)
import { vDrag } from '@vueuse/gesture'import { DragDirective } from '@vueuse/gesture'; app.directive('drag', DragDirective); - usePinch
import { usePinch } from '@vueuse/gesture'
Quickstart
<template>
<!-- Bind it to a component -->
<div v-bind="bind()" :style="style" class="box"></div>
</template>
<script lang="ts">
import { useDrag } from '@vueuse/gesture'
import { useSpring } from 'vue-use-spring'
import { defineComponent, computed } from 'vue'
export default defineComponent({
setup() {
const [{ x, y }, set] = useSpring(() => ({ x: 0, y: 0 }))
// Set the drag hook and define component movement based on gesture data
const bind = useDrag(({ down, movement: [mx, my] }) => {
set({ x: down ? mx : 0, y: down ? my : 0 })
})
const style = computed(() => ({
transform: `translate3d(${x.value}px,${y.value}px,0)`,
touchAction: 'none' // Crucial for preventing browser native scrolling glitches
}))
return { bind, style }
},
})
</script>
<style scoped>
.box {
width: 100px;
height: 100px;
background: #42b983;
border-radius: 8px;
cursor: grab;
user-select: none;
}
.box:active {
cursor: grabbing;
}
</style>