🎧 useEventListener - イベントリスナーの神器
🌟 紹介
あなたのコンポーネントが賢明な世話人のように、適切なタイミングで様々なイベントを自動的にリッスンし、離れるときには優雅に掃除してくれることを想像してください。useEventListener はまさにそのような親切なアシスタントです!
これはコンポーネントの mounted と activated の際に自動的にイベントをバインドし、unmounted と deactivated の際に自動的にイベントをアンバインドします。手動でイベントリスナーを管理する煩わしさから解放されます。ウィンドウサイズの変化、マウスクリック、キーボード入力など、どんなイベントも簡単に処理できます!
🚀 コードデモ
基本的な使い方 - ウィンドウイベントのリッスン
js
import { ref } from 'vue';
import { useEventListener } from '@vant/use';
export default {
setup() {
// 🪟 ウィンドウサイズ変化のリッスン
useEventListener('resize', () => {
console.log('ウィンドウサイズが変わりました!');
});
// 📱 デバイスの向き変化のリッスン
useEventListener('orientationchange', () => {
console.log('デバイスの向きが変わりました!');
});
// ⌨️ キーボードイベントのリッスン
useEventListener('keydown', (event) => {
if (event.key === 'Escape') {
console.log('ユーザーがESCキーを押しました');
}
});
},
};ターゲット要素を指定 - 精確なリッスン
js
import { ref, onMounted } from 'vue';
import { useEventListener } from '@vant/use';
export default {
setup() {
const buttonRef = ref();
const containerRef = ref();
onMounted(() => {
// 🎯 特定ボタンのクリックをリッスン
useEventListener(
'click',
() => {
console.log('ボタンがクリックされました!');
},
{ target: buttonRef }
);
// 📦 コンテナのスクロールイベントをリッスン
useEventListener(
'scroll',
(event) => {
console.log('コンテナのスクロール位置:', event.target.scrollTop);
},
{ target: containerRef }
);
});
return {
buttonRef,
containerRef,
};
},
};手動でのクリーンアップ - 柔軟な制御
js
import { ref } from 'vue';
import { useEventListener } from '@vant/use';
export default {
setup() {
const isListening = ref(true);
// 🧹 クリーンアップ関数を取得
const cleanup = useEventListener('resize', () => {
console.log('ウィンドウサイズが変更されました');
});
// 🎛️ リッスン状態を動的に制御
const toggleListener = () => {
if (isListening.value) {
cleanup(); // リッスンを停止
isListening.value = false;
} else {
// リッスンを再開
useEventListener('resize', () => {
console.log('ウィンドウの変化のリッスンを再開しました');
});
isListening.value = true;
}
};
return {
isListening,
toggleListener,
};
},
};高度な設定 - パフォーマンスの最適化
js
import { ref } from 'vue';
import { useEventListener } from '@vant/use';
export default {
setup() {
const scrollContainer = ref();
// 🚀 passive モードを使用してスクロールパフォーマンスを最適化
useEventListener(
'scroll',
(event) => {
// preventDefault を呼び出さないため、パフォーマンスが向上します
console.log('スクロール位置:', event.target.scrollTop);
},
{
target: scrollContainer,
passive: true, // スクロールパフォーマンスを向上
}
);
// 🎯 キャプチャモードを使用
useEventListener(
'click',
(event) => {
console.log('キャプチャフェーズでクリックイベントを処理');
},
{
target: document.body,
capture: true, // キャプチャフェーズでトリガー
}
);
return {
scrollContainer,
};
},
};モバイル対応 - タッチイベント
js
import { ref } from 'vue';
import { useEventListener } from '@vant/use';
export default {
setup() {
const touchArea = ref();
const startPos = ref({ x: 0, y: 0 });
// 👆 タッチ開始
useEventListener(
'touchstart',
(event) => {
const touch = event.touches[0];
startPos.value = {
x: touch.clientX,
y: touch.clientY,
};
},
{ target: touchArea, passive: true }
);
// 👆 タッチ移動
useEventListener(
'touchmove',
(event) => {
const touch = event.touches[0];
const deltaX = touch.clientX - startPos.value.x;
const deltaY = touch.clientY - startPos.value.y;
console.log('スライド距離:', { deltaX, deltaY });
},
{ target: touchArea, passive: true }
);
return {
touchArea,
};
},
};📚 API リファレンス
型定義
ts
type Options = {
target?: EventTarget | Ref<EventTarget>;
capture?: boolean;
passive?: boolean;
};
function useEventListener(
type: string,
listener: EventListener,
options?: Options,
): () => void;パラメータの説明
| パラメータ | 説明 | 型 | デフォルト値 |
|---|---|---|---|
| type | 🎯 リッスンするイベントタイプ('click', 'resize', 'scroll' など) | string | - |
| listener | 🎧 イベントコールバック関数 | EventListener | - |
| options | ⚙️ オプションの設定項目 | Options | - |
Options 設定
| パラメータ | 説明 | 型 | デフォルト値 |
|---|---|---|---|
| target | 🎯 イベントをバインドするターゲット要素 | EventTarget | Ref<EventTarget> | window |
| capture | 📥 イベントキャプチャフェーズでトリガーするかどうか | boolean | false |
| passive | 🚀 true に設定すると、listener が preventDefault を呼び出さないことを示し、パフォーマンスが向上します | boolean | false |
戻り値
| 型 | 説明 |
|---|---|
| () => void | 🧹 クリーンアップ関数、呼び出すとイベントリスナーが削除されます |
🎯 実際のアプリケーションシナリオ
📱 モバイル端末のジェスチャー認識
js
// 左右スワイプ切り替えの実装
const useSwipeGesture = (onSwipeLeft, onSwipeRight) => {
let startX = 0;
useEventListener('touchstart', (e) => {
startX = e.touches[0].clientX;
}, { passive: true });
useEventListener('touchend', (e) => {
const endX = e.changedTouches[0].clientX;
const diff = startX - endX;
if (Math.abs(diff) > 50) {
diff > 0 ? onSwipeLeft() : onSwipeRight();
}
}, { passive: true });
};🖥️ レスポンシブレイアウトのリッスン
js
// 画面サイズの変化をリッスンし、動的にレイアウトを調整
const useResponsiveLayout = () => {
const isMobile = ref(window.innerWidth < 768);
useEventListener('resize', () => {
isMobile.value = window.innerWidth < 768;
});
return { isMobile };
};⌨️ ショートカットキーシステム
js
// グローバルショートカットキーの実装
const useHotkeys = () => {
useEventListener('keydown', (e) => {
if (e.ctrlKey && e.key === 's') {
e.preventDefault();
console.log('保存ショートカットキーがトリガーされました');
}
});
};💡 ベストプラクティス
✅ 推奨される方法
js
// 1. passive を使用してスクロールパフォーマンスを最適化
useEventListener('scroll', handler, { passive: true });
// 2. グローバルではなく特定の要素をリッスンする
useEventListener('click', handler, { target: buttonRef });
// 3. 必要なときに手動でクリーンアップする
const cleanup = useEventListener('resize', handler);
// ある条件下でクリーンアップ
if (shouldCleanup) cleanup();❌ 避けるべき使い方
js
// ❌ イベントハンドラーで時間のかかる操作を実行しない
useEventListener('scroll', () => {
// 複雑な計算は避ける
heavyComputation();
});
// ❌ タイマーなどの副作用のクリーンアップを忘れない
useEventListener('click', () => {
setInterval(() => {
// メモリリークの原因になる可能性がある
}, 1000);
});🛠️ デバッグのヒント
イベントリスナーの状態チェック
js
// デバッグ情報を追加
const cleanup = useEventListener('click', (e) => {
console.log('イベントがトリガーされました:', {
type: e.type,
target: e.target,
timestamp: Date.now(),
});
});
// 正しくクリーンアップされているか確認
onUnmounted(() => {
console.log('コンポーネントがアンマウントされました、イベントリスナーのクリーンアップを確認');
});性能监控
js
// イベントの頻度を監視
let eventCount = 0;
useEventListener('scroll', () => {
eventCount++;
if (eventCount % 100 === 0) {
console.log(`スクロールイベントが ${eventCount} 回トリガーされました`);
}
}, { passive: true });📚 関連ドキュメント
🎯 イベント処理関連
- useClickAway - クリック外領域 - 外側のクリック検出
- useToggle - ブール値切り替え - 状態切り替え管理
- usePageVisibility - ページ可視性 - ページ可視性の検出
📱 モバイル関連
- useRect - 要素位置 - 要素の位置情報を取得
- useScrollParent - スクロール親要素 - スクロールコンテナを見つける
- useWindowSize - ウィンドウサイズ - ウィンドウサイズのリッスン
🎨 UI インタラクション関連
- useRaf - アニメーションフレーム - アニメーションフレーム管理
- useRelation - コンポーネント関連 - 親子コンポーネント通信
🛠️ 開発ツール
- Vant Use 紹介 - コンポジション API ツールセット
- テーマカスタマイズ - スタイルテーマの設定