引言

在移動優先的時代,手勢操作已成為現代Web應用不可或缺的交互方式。傳統的點擊事件已經無法滿足用户對自然交互的期待。今天,我很高興向大家介紹我為Vue3開發的一套手勢指令庫,它將為你的應用帶來流暢、自然的手勢體驗!

為什麼需要手勢指令?

移動設備上的觸摸交互與桌面端的鼠標交互有本質不同:

  1. 觸摸屏沒有hover狀態
  2. 多點觸控支持
  3. 需要識別滑動方向、速度等複雜手勢
  4. 需要考慮觸摸反饋和防抖

傳統的@click事件在這些場景下顯得力不從心,而原生JavaScript實現手勢識別又過於複雜。這正是Vue3手勢指令要解決的問題。

安裝與基本使用

npm install vue3-gesture-directive
import { createApp } from 'vue'
import VueGesture from 'vue3-gesture-directive'

const app = createApp(App)
app.use(VueGesture)
app.mount('#app')

核心手勢指令

1. 滑動指令 (v-swipe)

<div
v-swipe="handleSwipe"
v-swipe:up="handleSwipeUp"
v-swipe:down.prevent="handleSwipeDown"
></div>

handleSwipe函數會接收到一個包含豐富信息的事件對象:

{
direction: 'left' | 'right' | 'up' | 'down',
velocity: number, // 滑動速度(px/ms)
distance: number, // 滑動距離
duration: number, // 持續時間
startEvent: TouchEvent,
endEvent: TouchEvent
}

2. 長按指令 (v-longpress)

<button
v-longpress="handleLongPress"
v-longpress:1000="handleLongPress" // 自定義觸發時間(ms)
></button>

3. 捏合縮放指令 (v-pinch)

<div
v-pinch="handlePinch"
v-pinch:rotate="handleRotate" // 同時支持旋轉
></div>

處理函數接收的參數包含縮放比例和旋轉角度:

{
scale: number, // 相對於初始值的比例
rotation: number, // 旋轉角度(deg)
center: { x: number, y: number } // 手勢中心點
}

4. 輕點指令 (v-tap)

比click更快的響應,解決了移動端click的300ms延遲問題。

<div v-tap="handleTap"></div>

高級特性

指令修飾符

所有指令都支持以下修飾符:

  • .prevent - 調用event.preventDefault()
  • .stop - 調用event.stopPropagation()
  • .self - 僅當事件是從觸發元素自身觸發時才觸發
  • .capture - 使用捕獲模式
<div v-swipe.left.prevent="handleLeftSwipe"></div>

組合手勢

可以同時使用多個手勢指令:

<div
v-tap="handleTap"
v-swipe="handleSwipe"
v-longpress="handleLongPress"
></div>

自定義閾值

可以通過插件選項全局設置或通過指令參數局部設置各種閾值:

app.use(VueGesture, {
swipeThreshold: 50, // 滑動識別閾值(px)
longPressThreshold: 500, // 長按識別時間(ms)
pinchThreshold: 0.1 // 縮放識別閾值
})

或在指令中:

<div v-swipe:100="handleSwipe"></div> <!-- 設置閾值為100px -->

性能優化

手勢識別可能會頻繁觸發事件,我們做了以下優化:

  1. 使用requestAnimationFrame節流事件處理
  2. 被動事件監聽器提高滾動性能
  3. 智能識別,避免不必要的手勢計算
  4. 輕量級的依賴(僅5kb gzipped)

與Vue3響應式系統的完美結合

手勢指令完全支持Vue3的響應式系統,你可以在手勢處理函數中直接修改狀態:

<template>
<div
v-swipe.left="x -= 10"
v-swipe.right="x += 10"
:style="{ transform: `translateX(${x}px)` }"
></div>
</template>

<script setup>
import { ref } from 'vue'
const x = ref(0)
</script>

實際應用案例

圖片瀏覽器

<template>
<div class="gallery">
<img
v-for="(img, index) in images"
:key="img.id"
:src="img.url"
v-swipe.left="nextImage"
v-swipe.right="prevImage"
v-pinch="handleZoom"
v-tap="toggleControls"
/>
</div>
</template>

可排序列表

<template>
<ul>
<li
v-for="item in list"
:key="item.id"
v-longpress="startDrag(item)"
v-swipe.up="moveUp(item)"
v-swipe.down="moveDown(item)"
>
{{ item.text }}
</li>
</ul>
</template>

與現有解決方案的比較

相比於其他手勢庫,vue3-gesture-directive有以下優勢:

  1. Vue原生集成 - 作為指令而非組件,更符合Vue的使用習慣
  2. 更輕量 - 只包含最常用的手勢,沒有冗餘代碼
  3. 更好的TS支持 - 完整的TypeScript類型定義
  4. 更靈活的配置 - 支持全局和局部的閾值配置

總結

Vue3手勢指令為移動端Web應用提供了強大而靈活的手勢識別能力,讓開發者能夠輕鬆實現自然流暢的交互體驗。無論是簡單的滑動操作,還是複雜的多點觸控手勢,都能通過簡潔的指令式API實現。

歡迎在GitHub上查看項目源碼並提交你的反饋和建議!讓我們一起打造更好的Vue手勢交互體驗。


項目地址: github.com/your-repo/vue3-gesture-directive

NPM包: vue3-gesture-directive

文檔: 手勢指令完整文檔