Uso de effectScope(), getCurrentScope() y onScopeDispose() en Vue

effectScope()

Documentación oficial: Crea un ámbito de efecto que puede capturar los efectos secundarios reactivos generados en su interior (como propiedades computadas y watchers), permitiendo gestionarlos de forma conjunta.

Explicación práctica: Podemos imaginarlo como un gestor de escuchas. Básicamente, agrupa dentro de una función las propiedades computadas y los watchers, para luego detener todas las escuchas de una sola vez.

import { effectScope, computed, watch, watchEffect, ref } from 'vue'

const contador = ref(5)

// Creamos un ámbito con effectScope
const ambito = effectScope()

ambito.run(() => {
  // Dentro de este bloque colocamos los efectos reactivos
  const doble = computed(() => contador.value * 2)

  watch(doble, (nuevoValor) => {
    console.log('El doble ha cambiado:', nuevoValor)
  })

  watchEffect(() => {
    console.log('Valor actual del doble:', doble.value)
  })
})

// Para detener todos los efectos dentro del ámbito
ambito.stop()

getCurrentScope()

Obtiene la instancia del ámbito de efecto activo en ese momento. Es útil cuando hay múltiples ámbitos y se desea detenerlos todos a la vez, sin tener que gestionar cada uno individualmente.

const todosLosAmbitos = getCurrentScope()
// Detiene todos los efectos del ámbito actual
todosLosAmbitos.stop()

onScopeDispose()

Función que registra un callback que se ejecuta cuando se detiene el ámbito actual (mediante getCurrentScope().stop()) o cuando el componente se desmonta.

onScopeDispose(() => {
  // Código de limpieza
  console.log('El ámbito ha sido detenido')
})

Ejemplo completo

<script setup>
import {
  ref,
  computed,
  watch,
  watchEffect,
  effectScope,
  getCurrentScope,
  onScopeDispose
} from 'vue'

const contador = ref(10)

// Primer ámbito
const ambito1 = effectScope()
ambito1.run(() => {
  const triple = computed(() => contador.value * 3)
  watch(triple, (val) => console.log('Triple:', val))
  watchEffect(() => console.log('Triple actual:', triple.value))
})
// ambito1.stop() // Detendría solo este ámbito, sin disparar onScopeDispose

// Segundo ámbito
const ambito2 = effectScope()
ambito2.run(() => {
  const cuadruple = computed(() => contador.value * 4)
  watch(cuadruple, (val) => console.log('Cuádruple:', val))
  watchEffect(() => console.log('Cuádruple actual:', cuadruple.value))
})
// ambito2.stop() // Similar

// Obtenemos el ámbito actual (el del script setup)
const ambitoActual = getCurrentScope()

// Al detener el ámbito actual se ejecutará onScopeDispose
onScopeDispose(() => {
  console.log('Todos los ámbitos han sido detenidos')
})

// Detenemos todo después de 5 segundos
setTimeout(() => {
  ambitoActual.stop()
}, 5000)
</script>

Etiquetas: Vue effectScope getCurrentScope onScopeDispose Composition API

Publicado el 5-29 12:55