El efecto mágico de watchEffect de Vue3, la diferencia con watch

prefacio

En Vue3, se introdujo la API de Composición, watchEffect()cuya función es una herramienta muy poderosa y flexible para manejar cambios en los datos receptivos, lo que hace que el proyecto sea más elástico y flexible. Es watchdiferente de y, este artículo presentará watchEffect()la definición, características, watchdiferencia entre y y precauciones al usar.

1. Definición

watchEffect()Las funciones se utilizan para crear un efecto secundario reactivo que rastrea automáticamente las dependencias. Se ejecutará inmediatamente cuando se inicialice , y rastreará automáticamente todos los datos reactivos utilizados en la función de devolución de llamada, y volverá a ejecutar la función de devolución de llamada cuando cambien los datos.

Por ejemplo,  todoId para usar un oyente para cargar un recurso remoto siempre que cambie la referencia, si usa un reloj, se escribe así:

<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>

Imprimir:

Pero watchEffect()se puede simplificar a:

<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>

 Imprimir:

Ambos imprimen datos inmediatamente. Pero en el siguiente ejemplo, la devolución de llamada se ejecutará inmediatamente sin especificar  immediate: true. Durante la ejecución, se rastrea automáticamente  todoId.value como una dependencia (similar a las propiedades calculadas). Cada vez que  todoId.value hay un cambio, la devolución de llamada se ejecuta nuevamente. Con eso  watchEffect(), ya no necesitamos pasar explícitamente  todoId como valor de origen.

Desde este punto de vista, watchEffect()el efecto es similar al de Vue2, computed,es decir, cuando cambian las dependencias, también cambian. Pero computeda diferencia de , watchEffect()no hay valor de retorno, sino que la función de devolución de llamada se ejecuta directamente.

2. Características

watchEffect()rastrea automáticamente todos los datos reactivos utilizados en sus devoluciones de llamada y vuelve a ejecutar las devoluciones de llamada cuando esos datos cambian. Esto hace que no sea necesario que especifiquemos manualmente las propiedades específicas que se van a monitorear , lo que reduce la redundancia del código.

    Para este ejemplo con solo una dependencia, watchEffect() el beneficio es relativamente pequeño. Pero para los oyentes con múltiples dependencias, el uso  watchEffect() puede eliminar la carga de mantener manualmente la lista de dependencias.

    Además, si necesita escuchar varias propiedades en una estructura de datos anidada, watchEffect() puede ser más eficiente que un detector profundo, ya que solo rastreará las propiedades utilizadas en la devolución de llamada, en lugar de rastrear recursivamente todas las propiedades. 

Ejemplo de múltiples dependencias:

<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>

Imprimir:

Ejemplos de dependencias profundas:

<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>

Imprimir:

3. La diferencia con el reloj.

1. El método de monitoreo es diferente : watchEffect()rastrea automáticamente todos los datos de respuesta utilizados, pero watchnecesita especificar manualmente los atributos específicos que se monitorearán.

2. La granularidad del monitoreo es diferente : watchEffect()lo que se monitorea es el cambio completo de los datos de respuesta, pero watchse puede monitorear el cambio del atributo o expresión especificados.

3. Las propiedades calculadas se manejan de manera diferente : para las propiedades calculadas, watchEffect()dependerá automáticamente de los datos de respuesta utilizados por la propiedad calculada, pero watchdebe especificar manualmente la propiedad calculada como el objetivo de monitoreo.

4. Asuntos que requieren atención

1. Evite la supervisión excesiva : dado que watchEffect()se realizará un seguimiento de todos los datos de respuesta utilizados, es necesario asegurarse de que solo se utilicen los datos de respuesta necesarios en la función de devolución de llamada para evitar una sobrecarga de representación innecesaria.

2. Las operaciones asíncronas deben manejarse con cuidado : dado que watchEffect()la función de devolución de llamada se ejecutará de inmediato, si se realizan operaciones asíncronas en la función de devolución de llamada, debe manejarse con cuidado para evitar comportamientos inesperados o efectos secundarios.

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

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

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

3. Evite los bucles infinitos : al watchEffect()modificar los datos de respuesta en las devoluciones de llamada, puede causar bucles infinitos. Para evitar este problema, use watch()funciones y establezca immediate: trueopciones, o use refpara almacenar datos temporales.

Supongo que te gusta

Origin blog.csdn.net/weixin_42373175/article/details/131780643
Recomendado
Clasificación