Vue3のwatchEffectの魔法効果、watchとの違い

序文

Vue3 では、Composition API が導入されました。watchEffect()この機能は、応答性の高いデータの変更を処理するための非常に強力で柔軟なツールであり、プロジェクトの弾力性と柔軟性を高めます。and とは異なりますが、この記事では定義や特徴、 and との違い、使用する際の注意点などwatchを紹介しますwatchEffect()watch

1. 定義

watchEffect()関数は、依存関係を自動的に追跡するリアクティブな副作用を作成するために使用されます。これは初期化されるとすぐに実行されコールバック関数で使用されるすべてのリアクティブ データを自動的に追跡し、データが変更されたときにコールバック関数を再実行します。

たとえば、 todoId 参照が変更されるたびにリスナーを使用してリモート リソースをロードするには、ウォッチを使用する場合は次のように記述します。

<template>
  <div>Test</div>
</template>

<script setup>
  import { ref, watch } from 'vue'
  const todoId = ref(1)
  const data = ref(null)

  watch(
    todoId,
    async () => {
      const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)
      data.value = await response.json()
      console.log(data.value)
    },
    { immediate: true }
  )
</script>

印刷:

しかし、次watchEffect()のように単純化することができます。

<template>
  <div>Test</div>
</template>

<script setup>
  import { ref, watchEffect } from 'vue'
  const todoId = ref(1)
  const data = ref(null)

  watchEffect(async () => {
    const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${todoId.value}`)
    data.value = await response.json()
    console.log(data.value)
  })
</script>

 印刷:

どちらもデータをすぐに印刷します。ただし、次の例では、 を指定せずにコールバックがすぐに実行されます immediate: true実行中、依存関係として自動的に追跡されます todoId.value (計算されたプロパティと同様)。todoId.value 変更があるたびに 、コールバックが再度実行されます。これにより watchEffect()、ソース値として明示的に渡す必要がなくなりました todoId 。

この観点から見ると、watchEffect()その効果は Vue2 の効果と似ています。computed,つまり、依存関係が変更されると、依存関係も変更されます。ただしcomputed、 とは異なり、watchEffect()戻り値はなく、コールバック関数が直接実行されます。

2. 特徴

watchEffect()は、コールバックで使用されるすべてのリアクティブ データを自動的に追跡し、それらのデータが変更されたときにコールバックを再実行します。これにより、監視する特定のプロパティを手動で指定する必要がなくなり、コードの冗長性が軽減されます。

    依存関係が 1 つだけあるこの例では、watchEffect() 利点は比較的小さいです。ただし、複数の依存関係を持つリスナーの場合、 を使用すると、 watchEffect() 依存関係リストを手動で保守する負担を軽減できます。

    また、ネストされたデータ構造内の複数のプロパティをリッスンする必要がある場合は、watchEffect() すべてのプロパティを再帰的に追跡するのではなく、コールバックで使用されるプロパティのみを追跡するため、ディープ リスナーより効率的である可能性があります。 

複数の依存関係の例:

<template>
  <div>Test</div>
</template>

<script setup>
  import { reactive } from 'vue'
  const state = reactive({
    count: 0,
    name: 'John',
    age: 25
  })

  // 使用watchEffect()监听count和name的变化
  watchEffect(() => {
    console.log('count or name changed:', state.count, state.name)
  })

  // 模拟count和name变化
  setTimeout(() => {
    state.count = 1 // 输出'count or name changed: 1 John'
    state.name = 'Alice' // 输出'count or name changed: 1 Alice'
  }, 1000)
</script>

印刷:

深い依存関係の例:

<template>
  <div>Test</div>
</template>

<script setup>
  import { reactive, watchEffect } from 'vue'
  const state = reactive({
    person: {
      name: 'John',
      age: 25
    },
    todos: [
      { text: 'Task 1', completed: false },
      { text: 'Task 2', completed: true },
      { text: 'Task 3', completed: false }
    ]
  })

  // 使用watchEffect()监听person对象中name和age的变化
  watchEffect(() => {
    console.log('person changed:', state.person.name, state.person.age)
  })

  // 模拟person中name和age的变化
  setTimeout(() => {
    state.person.name = 'Alice' // 输出'person changed: Alice 25'
    state.person.age = 30 // 输出'person changed: Alice 30'
  }, 1000)
</script>

印刷:

3. 時計との違い

1. 監視方法が異なりますwatchEffect()使用されるすべての応答データを自動的に追跡しますが、watch監視する特定の属性を手動で指定する必要があります。

2. 監視の粒度が異なりますwatchEffect()監視されるのは応答データの変更全体ですが、watch指定された属性または式の変更も監視できます。

3. 計算プロパティの処理が異なる: 計算プロパティの場合、watchEffect()計算プロパティで使用される応答データに自動的に依存しますが、watch計算プロパティを監視対象として手動で指定する必要があります。

4. 注意すべき事項

1. 過剰な監視を避ける:watchEffect()使用されるすべての応答データが追跡されるため、不要なレンダリングのオーバーヘッドを避けるために、コールバック関数で必要な応答データのみが使用されるようにする必要があります。

2. 非同期操作は慎重に処理する必要がありますwatchEffect()コールバック関数はすぐに実行されるため、コールバック関数内で非同期操作が実行される場合は、予期しない動作や副作用を避けるために慎重に処理する必要があります。

<script setup>
import { watchEffect } from 'vue'

// 它会自动停止
watchEffect(() => {})

// ...这个则不会!
setTimeout(() => {
  watchEffect(() => {})
}, 100)
</script>

3. 無限ループを避ける:watchEffect()コールバック内の応答データを変更すると、無限ループが発生する可能性があります。この問題を回避するには、watch()関数を使用してimmediate: trueオプションを設定するか、 を使用してref一時データを保存します。

おすすめ

転載: blog.csdn.net/weixin_42373175/article/details/131780643