ベストプラクティス
分割代入
VueUseの関数のほとんどは、必要なものを取り出すためにES6のオブジェクト分割代入構文を使用できる**refのオブジェクト**を返します。例:
import { useMouse } from '@vueuse/core'
// "x" and "y" are refs
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" and "y" will be auto unwrapped, no `.value` needed
console.log(mouse.x)
副作用のクリーンアップ
コンポーネントがアンマウントされたときに破棄されるVueのwatch
やcomputed
と同様に、VueUseの関数も副作用を自動的にクリーンアップします。
たとえば、useEventListener
は、コンポーネントがアンマウントされたときにremoveEventListener
を呼び出します。
// will cleanup automatically
useEventListener('mousemove', () => {})
すべてのVueUse関数はこの規約に従います。
副作用を手動で破棄するために、一部の関数はwatch
関数と同様にストップハンドラーを返します。例:
const stop = useEventListener('mousemove', () => {})
// ...
// unregister the event listener manually
stop()
すべての関数がstop
ハンドラーを返すわけではないため、より一般的な解決策は、VueのeffectScope
APIを使用することです。
import { effectScope } from 'vue'
const scope = effectScope()
scope.run(() => {
// ...
useEventListener('mousemove', () => {})
onClickOutside(el, () => {})
watch(source, () => {})
})
// all composables called inside `scope.run` will be disposed
scope.stop()
effectScope
の詳細については、このRFCをご覧ください。
リアクティブな引数
Vueでは、setup()
関数を使用してデータとロジックの間の「接続」を構築します。柔軟性を持たせるために、ほとんどのVueUse関数は、refがリアクティブであるため、引数にrefも受け入れます。
useTitle
を例にとってみましょう。
非リアクティブな引数
useTitle
コンポーザブルは、現在のページのdocument.title
プロパティを取得および設定するのに役立ちます。
const isDark = useDark()
const title = useTitle('Hello')
console.log(document.title) // "Hello"
watch(isDark, () => {
title.value = isDark.value ? '🌙 Good evening!' : '☀️ Good morning!'
})
Ref引数
返されたrefを使用する代わりに、refをuseTitle
に渡すことができます。
const isDark = useDark()
const title = computed(() => isDark.value ? '🌙 Good evening!' : '☀️ Good morning!')
useTitle(title)
リアクティブなゲッター引数
VueUse 9.0以降、リアクティブオブジェクトやリアクティビティ変換とうまく連携する「リアクティブゲッター」を引数として渡すための新しい規約を導入しました。
const isDark = useDark()
useTitle(() => isDark.value ? '🌙 Good evening!' : '☀️ Good morning!')