日本語

Vue.js 3 Composition APIを徹底解説。世界中の開発者向けに、再利用可能で保守・テストしやすいVue.jsアプリケーションを構築するための実践的な例とベストプラクティスを学びます。

Vue.js 3 Composition API: グローバル開発者向けの徹底解説

Vue.jsは、その親しみやすい学習曲線と強力な機能のおかげで、現代的なWebアプリケーションを構築するための人気のある選択肢として急速に普及しました。Vue.js 3では、コンポーネントのロジックを整理する新しい方法であるComposition APIが導入され、これをさらに進化させました。この徹底解説では、Composition APIを効果的に理解し活用するための包括的なガイドを提供し、より保守性が高く、再利用可能で、テストしやすいVueアプリケーションを構築するスキルを身につけることができます。

Composition APIとは?

Composition APIは、オプションを宣言する代わりに、インポートされた関数を使用してVueコンポーネントを作成できるようにするAPIのセットです。基本的には、関連するロジックをテンプレート内のどこに現れるかに関わらず、一緒にグループ化することができます。これは、コードを事前定義されたカテゴリに基づいて整理することを強制するOptions API(data, methods, computed, watch)とは対照的です。Options APIはコードを*それが何か*(データ、メソッドなど)で整理するものと考えるのに対し、Composition APIはコードを*それが何をするか*で整理できるものと考えることができます。

Composition APIの中核はsetup()関数を中心に展開されます。この関数は、コンポーネント内でComposition APIを利用するためのエントリーポイントです。setup()内では、リアクティブな状態、算出プロパティ、メソッド、ライフサイクルフックをコンポーザブル関数を使用して定義できます。

なぜComposition APIを使用するのか?

Composition APIは、特に大規模で複雑なアプリケーションにおいて、従来のOptions APIに比べていくつかの利点を提供します:

コアコンセプトの理解

Composition APIを支える主要な概念について詳しく見ていきましょう:

1. setup()

前述の通り、setup()はComposition APIを使用するためのエントリーポイントです。これは、コンポーネントが作成される前に実行されるコンポーネントオプションです。setup()内で、リアクティブな状態、算出プロパティ、メソッド、ライフサイクルフックを定義し、テンプレートに公開したい値を含むオブジェクトを返します。

例:

import { ref } from 'vue'

export default {
  setup() {
    const count = ref(0)

    const increment = () => {
      count.value++
    }

    return {
      count,
      increment
    }
  }
}

この例では、refを使用してcountというリアクティブな変数を作成しています。また、countの値を増やすincrementというメソッドを定義しています。最後に、countincrementを含むオブジェクトを返し、これらをコンポーネントのテンプレートで利用できるようにします。

2. refreactiveによるリアクティブな状態

Composition APIは、リアクティブな状態を作成するための2つの主要な関数、refreactiveを提供します。

refを使用した例:

import { ref } from 'vue'

export default {
  setup() {
    const message = ref('Hello, Vue!')

    const updateMessage = (newMessage) => {
      message.value = newMessage
    }

    return {
      message,
      updateMessage
    }
  }
}

reactiveを使用した例:

import { reactive } from 'vue'

export default {
  setup() {
    const state = reactive({
      name: 'John Doe',
      age: 30
    })

    const updateName = (newName) => {
      state.name = newName
    }

    return {
      state,
      updateName
    }
  }
}

3. computedによる算出プロパティ

算出プロパティは、他のリアクティブな状態から派生する値です。依存関係が変更されるたびに自動的に更新されます。computed関数は、ゲッター関数を引数として受け取り、読み取り専用のリアクティブなrefを返します。

例:

import { ref, computed } from 'vue'

export default {
  setup() {
    const firstName = ref('John')
    const lastName = ref('Doe')

    const fullName = computed(() => {
      return `${firstName.value} ${lastName.value}`
    })

    return {
      firstName,
      lastName,
      fullName
    }
  }
}

この例では、fullNamefirstNamelastNameに依存する算出プロパティです。firstNameまたはlastNameのいずれかが変更されると、fullNameは自動的に更新されます。

4. watchwatchEffectによるウォッチャー

ウォッチャーを使用すると、リアクティブな状態の変化に反応できます。Composition APIは、ウォッチャーを作成するための2つの主要な方法、watchwatchEffectを提供します。

watchを使用した例:

import { ref, watch } from 'vue'

export default {
  setup() {
    const count = ref(0)

    watch(
      count,
      (newValue, oldValue) => {
        console.log(`Count changed from ${oldValue} to ${newValue}`)
      }
    )

    const increment = () => {
      count.value++
    }

    return {
      count,
      increment
    }
  }
}

watchEffectを使用した例:

import { ref, watchEffect } from 'vue'

export default {
  setup() {
    const message = ref('Hello')

    watchEffect(() => {
      console.log(`Message is: ${message.value}`)
    })

    const updateMessage = (newMessage) => {
      message.value = newMessage
    }

    return {
      message,
      updateMessage
    }
  }
}

5. ライフサイクルフック

Composition APIは、onMountedonUpdatedonUnmountedなど、onで始まる関数を通じてコンポーネントのライフサイクルフックへのアクセスを提供します。これらの関数は、引数としてコールバックを取り、対応するライフサイクルフックがトリガーされたときに実行されます。

例:

import { onMounted, onUnmounted } from 'vue'

export default {
  setup() {
    onMounted(() => {
      console.log('Component is mounted')
    })

    onUnmounted(() => {
      console.log('Component is unmounted')
    })

    return {}
  }
}

コンポーザブル関数の作成

Composition APIの真の力は、再利用可能なコンポーザブル関数を作成できることにあります。コンポーザブル関数とは、コンポーネントロジックの一部をカプセル化し、複数のコンポーネントで使用できるリアクティブな状態と関数を返す単なる関数です。

例:マウスの位置を追跡するコンポーザブル関数を作成してみましょう:

import { ref, onMounted, onUnmounted } from 'vue'

export function useMousePosition() {
  const x = ref(0)
  const y = ref(0)

  const updatePosition = (event) => {
    x.value = event.clientX
    y.value = event.clientY
  }

  onMounted(() => {
    window.addEventListener('mousemove', updatePosition)
  })

  onUnmounted(() => {
    window.removeEventListener('mousemove', updatePosition)
  })

  return {
    x,
    y
  }
}

これで、このコンポーザブル関数を任意のコンポーネントで使用できます:

import { useMousePosition } from './useMousePosition'

export default {
  setup() {
    const { x, y } = useMousePosition()

    return {
      x,
      y
    }
  }
}

実践的な例とユースケース

Composition APIが実際のシナリオでどのように使用できるか、いくつかの実践的な例を見ていきましょう:

1. データフェッチ

APIからデータを取得するためのコンポーザブル関数を作成するのは一般的なユースケースです。これにより、同じデータ取得ロジックを複数のコンポーネントで再利用できます。

import { ref, onMounted } from 'vue'

export function useFetch(url) {
  const data = ref(null)
  const error = ref(null)
  const loading = ref(true)

  onMounted(async () => {
    try {
      const response = await fetch(url)
      data.value = await response.json()
    } catch (err) {
      error.value = err
    } finally {
      loading.value = false
    }
  })

  return {
    data,
    error,
    loading
  }
}

その後、このコンポーザブル関数をコンポーネントで次のように使用できます:

import { useFetch } from './useFetch'

export default {
  setup() {
    const { data, error, loading } = useFetch('https://api.example.com/data')

    return {
      data,
      error,
      loading
    }
  }
}

2. フォームバリデーション

フォームバリデーションは、Composition APIが非常に役立つもう1つの分野です。バリデーションロジックをカプセル化するコンポーザブル関数を作成し、さまざまなフォームで再利用できます。

import { ref } from 'vue'

export function useValidation() {
  const errors = ref({})

  const validateField = (fieldName, value, rules) => {
    let error = null
    for (const rule of rules) {
      if (rule === 'required' && !value) {
        error = 'This field is required'
        break
      } else if (rule === 'email' && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(value)) {
        error = 'Invalid email format'
        break
      }
    }

    if (error) {
      errors.value[fieldName] = error
    } else {
      delete errors.value[fieldName]
    }
  }

  return {
    errors,
    validateField
  }
}

コンポーネントでの使用方法:

import { useValidation } from './useValidation'
import { ref } from 'vue'

export default {
  setup() {
    const { errors, validateField } = useValidation()
    const email = ref('')

    const validateEmail = () => {
      validateField('email', email.value, ['required', 'email'])
    }

    return {
      email,
      errors,
      validateEmail
    }
  }
}

3. ユーザー認証の管理

認証ロジックはしばしば複雑で、複数のコンポーネントで重複することがあります。Composition APIを使用すると、すべての認証ロジックをカプセル化し、コンポーネントが使用するためのクリーンなAPIを提供するコンポーザブル関数を作成できます。

例:(簡易版)

import { ref } from 'vue'

export function useAuth() {
  const isLoggedIn = ref(false)
  const user = ref(null)

  const login = async (username, password) => {
    // Simulate API call
    await new Promise(resolve => setTimeout(resolve, 1000))
    isLoggedIn.value = true
    user.value = { username }
  }

  const logout = async () => {
    // Simulate API call
    await new Promise(resolve => setTimeout(resolve, 1000))
    isLoggedIn.value = false
    user.value = null
  }

  return {
    isLoggedIn,
    user,
    login,
    logout
  }
}

Composition APIを使用するためのベストプラクティス

Composition APIを最大限に活用するために、以下のベストプラクティスを検討してください:

一般的な落とし穴とその回避方法

Composition APIは多くの利点を提供しますが、注意すべき一般的な落とし穴もいくつかあります:

Composition APIとグローバルチーム

Composition APIは、以下を促進することにより、グローバルな開発チーム内でのコラボレーションを育みます:

結論

Vue.js 3 Composition APIは、Vueアプリケーションの構成、再利用性、テスト可能性を大幅に向上させることができる強力なツールです。この徹底解説で概説されたコアコンセプトを理解し、ベストプラクティスに従うことで、Composition APIを活用して、グローバルなオーディエンス向けにより保守性が高くスケーラブルなアプリケーションを構築できます。Composition APIを取り入れて、Vue.js 3のポテンシャルを最大限に引き出しましょう。

自身のプロジェクトでComposition APIを試してみて、それが提供する広大な可能性を探求することをお勧めします。ハッピーコーディング!