ホームページ > ウェブフロントエンド > jsチュートリアル > 知っておくべき Vue コンポーザブルのヒント

知っておくべき Vue コンポーザブルのヒント

Susan Sarandon
リリース: 2025-01-11 08:46:44
オリジナル
623 人が閲覧しました

Vue Composables Tips You Need to Know

Vue コンポーザブルは非常に強力ですが、注意しないとすぐに乱雑になり、保守が困難になる可能性があります。

そのため、より優れた、より保守しやすいコンポーザブルを作成するのに役立つ 13 のヒントを特定しました。

単純な状態管理ソリューションを構築している場合でも、複雑な共有ロジックを構築している場合でも、以下のヒントが役に立ちます。

  • スパゲッティ コードにつながる一般的な落とし穴を回避します
  • テストと保守が簡単なコンポーザブルを作成します
  • より柔軟で再利用可能な共有ロジックを作成する
  • 必要に応じて、オプション API からコンポジション API に段階的に移行します

あなたが学ぶヒントは次のとおりです:

  1. 複数のコンポーネントを貫通する支柱の穴あけは避けてください
  2. 関連のないコンポーネント間でデータを共有する
  3. 明確なメソッドによる状態更新の制御
  4. 大きなコンポーネントを小さな関数に分割する
  5. ビジネス ロジックを Vue の反応性から分離する
  6. 同期データと非同期データの両方を 1 つの関数で処理します
  7. 関数パラメータをよりわかりやすくする
  8. デフォルト値による未定義のオプションの防止
  9. ニーズに基づいて単純な値または複雑な値を返します
  10. 異なるロジック パスを独自の関数に分離する
  11. リアクティブ値と生の値を一貫して処理します
  12. Ref アンラップの簡素化
  13. オプション API からコンポジション API に段階的に移行します

各パターンを詳しく見て、Vue アプリケーションをどのように改善できるかを見てみましょう。

そして、お気に入りのヒントを下にコメントすることを忘れないでください!

1. 複数のコンポーネントを貫通する支柱の穴あけを避ける

データ ストア パターンは、複数のコンポーネント レイヤーを介してプロパティやイベントを渡すことを回避するのに役立ちます。

1 つの状況は、無限のプロップドリルとイベントバブリングを通じて親子が通信している場合です。

<!-- Parent.vue -->
<template>
  <!-- But many more layers of components -->
  <Child :user="user" @change="onUserChange" />
</template>

<script setup>
const user = ref({ name: 'Alice' })
function onUserChange(updatedUser) {
  user.value = updatedUser
}
</script>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

これらのプロパティとイベントはコンポーネント階層内を行き来する必要があるため、非常に複雑になります。

より簡単な解決策は、任意のコンポーネントがインポートできる共有データ ストアを作成することです。

import { reactive, toRefs } from 'vue'
const state = reactive({ user: { name: 'Alice' } })

export function useUserStore() {
  return toRefs(state)
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

2. 無関係なコンポーネント間でデータを共有する

データ ストア パターンは、兄弟または「いとこ」コンポーネントが直接接続せずに同じデータを共有する必要がある場合にも役立ちます。

2 人の兄弟がどちらも同じユーザー オブジェクトを必要としているとします。しかし、プロップやイベントのためのエレガントなパスがありません。

これにより、多くの場合、親または重複した状態を介してデータを扱いにくくすることになります。

より良いアプローチは、両方の兄弟が利用できる単一のコンポーザブル ストアに依存することです。

// SiblingA.vue
import { useUserStore } from './useUserStore'
const { user } = useUserStore()

// SiblingB.vue
import { useUserStore } from './useUserStore'
const { user } = useUserStore()
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

3. 明確なメソッドによる状態更新の制御

データ ストア パターンは、共有状態を更新するための明確な方法を提供することを奨励します。

開発者の中には、次のようにリアクティブ オブジェクト全体を世界に公開する人もいます。

<!-- Parent.vue -->
<template>
  <!-- But many more layers of components -->
  <Child :user="user" @change="onUserChange" />
</template>

<script setup>
const user = ref({ name: 'Alice' })
function onUserChange(updatedUser) {
  user.value = updatedUser
}
</script>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

これにより、誰でも任意のファイルからユーザーの darkMode プロパティを直接変更できるようになり、分散した制御不能な変異が発生する可能性があります。

より良いアイデアは、更新がどのように行われるかを定義する関数とともに読み取り専用として状態を返すことです。

import { reactive, toRefs } from 'vue'
const state = reactive({ user: { name: 'Alice' } })

export function useUserStore() {
  return toRefs(state)
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

4. 大きなコンポーネントを小さな機能に分割する

インライン コンポーザブル パターンは、関連する状態とロジックを小さな関数に収集することで、大きなコンポーネントを分割するのに役立ちます。

巨大なコンポーネントでは、そのすべての参照とメソッドが 1 か所に配置される場合があります。

// SiblingA.vue
import { useUserStore } from './useUserStore'
const { user } = useUserStore()

// SiblingB.vue
import { useUserStore } from './useUserStore'
const { user } = useUserStore()
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

そのセットアップはすぐに管理できなくなります。

代わりに、インライン コンポーザブルはロジックをグループ化し、ローカルに提供できます。後でそれを別のファイルに抽出できます:

export const user = reactive({ darkMode: false })
ログイン後にコピー
ログイン後にコピー

5. ビジネス ロジックを Vue の反応性から分離する

Thin Composables パターンは、生のビジネス ロジックを Vue の反応性から分離することを指示し、テストとメンテナンスが簡素化されます。

すべてのロジックをコンポーザブルに埋め込むことができます:

import { reactive, readonly } from 'vue'
const state = reactive({ darkMode: false })

export function toggleDarkMode() {
  state.darkMode = !state.darkMode
}

export function useUserStore() {
  return {
    darkMode: readonly(state.darkMode),
    toggleDarkMode
  }
}
ログイン後にコピー
ログイン後にコピー

これにより、Vue 環境内でロジックをテストする必要があります。

代わりに、複雑なルールを純粋な関数に保持し、コンポーザブルでリアクティブ ラッパーのみを処理できるようにします。

<script setup>
const count = ref(0)
const user = ref({ name: 'Alice' })
// 500 more lines of intertwined code with watchers, methods, etc.
</script>
ログイン後にコピー
ログイン後にコピー

6. 同期データと非同期データの両方を 1 つの関数で処理する

Async Sync コンポーザブル パターンは、個別の関数を作成するのではなく、同期動作と非同期動作の両方を 1 つのコンポーザブルにマージします。

これは、Nuxt の useAsyncData の仕組みとまったく同じです。

ここには、Promise を返すと同時に、同期使用のための即時リアクティブ プロパティも提供できる単一のコンポーザブルがあります。

<script setup>
function useCounter() {
  const count = ref(0)
  const increment = () => count.value++
  return { count, increment }
}

const { count, increment } = useCounter()
</script>
ログイン後にコピー
ログイン後にコピー

7. 関数パラメータをよりわかりやすくする

オプション オブジェクト パターンは、単一の構成オブジェクトを期待することでパラメータの長いリストを整理できます。

このような呼び出しは面倒で間違いが発生しやすく、新しいオプションを追加するには関数シグネチャを更新する必要があります。

export function useCounter() {
  const count = ref(0)
  function increment() {
    count.value = (count.value * 3) / 2
  }
  return { count, increment }
}
ログイン後にコピー
ログイン後にコピー

それぞれの引数が何を意味するのかは明らかではありません。

オプション オブジェクトを受け入れるコンポーザブルは、すべてを説明的に保ちます。

// counterLogic.js
export function incrementCount(num) {
  return (num * 3) / 2
}

// useCounter.js
import { ref } from 'vue'
import { incrementCount } from './counterLogic'

export function useCounter() {
  const count = ref(0)
  function increment() {
    count.value = incrementCount(count.value)
  }
  return { count, increment }
}
ログイン後にコピー
ログイン後にコピー

8. デフォルト値による未定義のオプションの防止

オプション オブジェクト パターンでは、各プロパティのデフォルト値も推奨されています。

特定のフィールドが存在することを前提とする関数は、フィールドが渡されないと問題が発生する可能性があります:

import { ref } from 'vue'

export function useAsyncOrSync() {
  const data = ref(null)
  const promise = fetch('/api')
    .then(res => res.json())
    .then(json => {
      data.value = json
      return { data }
    })
  return Object.assign(promise, { data })
}
ログイン後にコピー
ログイン後にコピー

安全なデフォルトを使用してオプションを構造化することをお勧めします:

useRefHistory(someRef, true, 10, 500, 'click', false)
ログイン後にコピー

9. ニーズに基づいて単純な値または複雑な値を返す

動的リターン パターンにより、コンポーザブルは単純なユースケースでは単一の値を返すことも、より高度なコントロールを備えた展開されたオブジェクトを返すこともできます。

一部のアプローチは常にすべてを含むオブジェクトを返します:

<!-- Parent.vue -->
<template>
  <!-- But many more layers of components -->
  <Child :user="user" @change="onUserChange" />
</template>

<script setup>
const user = ref({ name: 'Alice' })
function onUserChange(updatedUser) {
  user.value = updatedUser
}
</script>
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

メインのリアクティブ値のみを必要とする人は、余分なものを処理する必要があります。

条件付きで単一の参照またはオブジェクトを返すコンポーザブルは、次のことを解決します。

import { reactive, toRefs } from 'vue'
const state = reactive({ user: { name: 'Alice' } })

export function useUserStore() {
  return toRefs(state)
}
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

10. 異なるロジック パスを独自の関数に分離する

非表示のコンポーザブル パターンは、同じコンポーザブル内で相互排他的なロジックが混在することを避けるのに役立ちます。

一部のコードは複数のモードまたはコード パスをひとまとめにしています:

// SiblingA.vue
import { useUserStore } from './useUserStore'
const { user } = useUserStore()

// SiblingB.vue
import { useUserStore } from './useUserStore'
const { user } = useUserStore()
ログイン後にコピー
ログイン後にコピー
ログイン後にコピー

各パスを独自のコンポーザブルに分割すると、より明確になり、機能には影響しません。

export const user = reactive({ darkMode: false })
ログイン後にコピー
ログイン後にコピー

11. リアクティブ値と生の値を一貫して処理する

柔軟な引数パターンにより、コンポーザブルの入力と出力がリアクティブ データまたは生の値として均一に処理され、混乱が回避されます。

一部のコードは、入力が参照であるかどうかをチェックします。

import { reactive, readonly } from 'vue'
const state = reactive({ darkMode: false })

export function toggleDarkMode() {
  state.darkMode = !state.darkMode
}

export function useUserStore() {
  return {
    darkMode: readonly(state.darkMode),
    toggleDarkMode
  }
}
ログイン後にコピー
ログイン後にコピー

代わりに、すぐに変換できます。

ref を使用すると、入力が ref の場合、その ref が返されます。それ以外の場合は、ref:
に変換されます。

<script setup>
const count = ref(0)
const user = ref({ name: 'Alice' })
// 500 more lines of intertwined code with watchers, methods, etc.
</script>
ログイン後にコピー
ログイン後にコピー

12. Ref アンラップの簡素化

柔軟な引数パターンは、ラップ解除が必要な場合にも toValue を使用します。

これがないと、コードは isRef チェックを実行し続ける可能性があります:

<script setup>
function useCounter() {
  const count = ref(0)
  const increment = () => count.value++
  return { count, increment }
}

const { count, increment } = useCounter()
</script>
ログイン後にコピー
ログイン後にコピー

呼び出し方ははるかに簡単です:

export function useCounter() {
  const count = ref(0)
  function increment() {
    count.value = (count.value * 3) / 2
  }
  return { count, increment }
}
ログイン後にコピー
ログイン後にコピー

13. オプション API からコンポジション API に段階的に移行する

オプションから合成パターンへの移行により、大きなオプション API コンポーネントを段階的に簡単に段階的に合成 API に移行できます。

従来のオプション コンポーネントでは次のことが行われます。

// counterLogic.js
export function incrementCount(num) {
  return (num * 3) / 2
}

// useCounter.js
import { ref } from 'vue'
import { incrementCount } from './counterLogic'

export function useCounter() {
  const count = ref(0)
  function increment() {
    count.value = incrementCount(count.value)
  }
  return { count, increment }
}
ログイン後にコピー
ログイン後にコピー

データ、計算されたプロパティ、メソッドが分散しています。

これをスクリプト設定に変換すると、それらがまとめられて理解しやすくなり、次のパターンを使用できるようになります。

import { ref } from 'vue'

export function useAsyncOrSync() {
  const data = ref(null)
  const promise = fetch('/api')
    .then(res => res.json())
    .then(json => {
      data.value = json
      return { data }
    })
  return Object.assign(promise, { data })
}
ログイン後にコピー
ログイン後にコピー

それをまとめる

これらの 13 のヒントは、アプリケーション全体での保守、テスト、再利用が容易な、より優れた Vue コンポーザブルを作成するのに役立ちます。

しかし、ここでは表面をなぞっただけです。

何年にもわたって、私はさらに多くのパターンとヒントを収集し、それらをすべてコンポーザブル パターンに関する詳細なコースにまとめました。

合計 16 のパターンがカバーされており、各パターンには次の内容があります:

  • 詳細な説明 —いつ使用するか、特殊なケース、およびバリエーション
  • 実際の例 — これらの単純な例を超えてそれらを使用する方法を確認できます
  • 段階的なリファクタリングの例 — 独自のコードに適用する方法を確認できます

詳細については、ここにアクセスしてください。

ああ、このコースは 1 月 15 日までセール中なので、今なら大幅割引で購入できます!

コンポーザブルなデザインパターンをチェックしてください

以上が知っておくべき Vue コンポーザブルのヒントの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート