Best Practice
ベストプラクティス
デストラクチャリング
VueUseのほとんどの関数は、必要なものを取り出すためにES6のオブジェクトデストラクチャリング構文を使用できるrefのオブジェクトを返します。例えば:
import { useMouse } from '@vueuse/core'
// "x" と "y" は ref
const { x, y } = useMouse()
console.log(x.value)
const mouse = useMouse()
console.log(mouse.x.value)
オブジェクトのプロパティとして使用したい場合は、reactive()
を使用してrefをアンラップできます。例えば:
import { useMouse } from '@vueuse/core'
import { reactive } from 'vue'
const mouse = reactive(useMouse())
// "x" と "y" は自動的にアンラップされ、`.value`は不要
console.log(mouse.x)
副作用のクリーンアップ
Vueのwatch
やcomputed
がコンポーネントがアンマウントされたときに破棄されるのと同様に、VueUseの関数も副作用を自動的にクリーンアップします。
例えば、useEventListener
はコンポーネントがアンマウントされたときにremoveEventListener
を呼び出します。
import { useEventListener } from '@vueuse/core'
// ---cut---
// 自動的にクリーンアップされます
useEventListener('mousemove', () => {})
すべてのVueUse関数はこの規約に従います。
副作用を手動で破棄するために、一部の関数はwatch
関数のようにストップハンドラーを返します。例えば:
import { useEventListener } from '@vueuse/core'
// ---cut---
const stop = useEventListener('mousemove', () => {})
// ...
// イベントリスナーを手動で解除
stop()
すべての関数がstop
ハンドラーを返すわけではないので、より一般的な解決策としてVueのeffectScope
APIを使用することができます。
import { effectScope } from 'vue'
const scope = effectScope()
scope.run(() => {
// ...
useEventListener('mousemove', () => {})
onClickOutside(el, () => {})
watch(source, () => {})
})
// `scope.run`内で呼び出されたすべてのコンポーザブルは破棄されます
scope.stop()
effectScope
についてはこのRFCで詳しく学ぶことができます。
リアクティブな引数
Vueでは、setup()
関数を使用してデータとロジックの「接続」を構築します。柔軟性を持たせるために、ほとんどのVueUse関数は引数としてrefを受け入れます。refはリアクティブだからです。
useTitle
を例にとります:
非リアクティブな引数
useTitle
コンポーザブルは、現在のページのdocument.title
プロパティを取得および設定するのに役立ちます。
// @lib: dom
import { useDark, useTitle } from '@vueuse/core'
import { watch } from 'vue'
// ---cut---
const isDark = useDark()
const title = useTitle('Hello')
console.log(document.title) // "Hello"
watch(isDark, () => {
title.value = isDark.value ? '🌙 Good evening!' : '☀️ Good morning!'
})
Ref引数
返されたrefを使用する代わりに、useTitle
にrefを渡すことができます。
import { useDark, useTitle } from '@vueuse/core'
import { computed } from 'vue'
// ---cut---
const isDark = useDark()
const title = computed(() => isDark.value ? '🌙 Good evening!' : '☀️ Good morning!')
useTitle(title)
リアクティブゲッター引数
VueUse 9.0以降、引数として「リアクティブゲッター」を渡す新しい規約を導入しました。これはリアクティブオブジェクトやReactivity Transformと非常に相性が良いです。
import { useDark, useTitle } from '@vueuse/core'
// ---cut---
const isDark = useDark()
useTitle(() => isDark.value ? '🌙 Good evening!' : '☀️ Good morning!')