Uso de keep-alive en Vue.js para la gestión de estados en caché

Método 1: Uso de metaetiquetas en rutas

1. En la definición de rutas, se añade una metaetiqueta keepAlive para indicar si se debe almacenar en caché.

{
  path: '/catalogo',
  name: 'catalogo',
  component: () => import('@/views/catalogo/catalogo.vue'),
  meta: {
    titulo: 'Catálogo de productos',
    keepAlive: true
  }
}

2. Al crear la instancia del router, se configura el método scrollBehavior para manejar la posición de desplazamiento.

const router = new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes,
  scrollBehavior(to, from, posicionGuardada) {
    if (posicionGuardada) {
      return posicionGuardada
    } else {
      return { x: 0, y: 0 }
    }
  }
})

3. En la plentilla, se envuelve el router-view con keep-alive según la metaetiqueta.

<keep-alive>
  <router-view v-if="$route.meta.keepAlive"></router-view>
</keep-alive>
<router-view v-if="!$route.meta.keepAlive"></router-view>

4. Para controlar el caché de manera condicional, se puede modificar la metaetiqueta en el gancho beforeRouteLeave del componente.

beforeRouteLeave(hacia, desde, siguiente) {
  this.cargando = true
  if (hacia.path === '/detalle_producto') {
    desde.meta.keepAlive = true
  } else {
    desde.meta.keepAlive = false
  }
  siguiente()
}

Este método tiene limitaciones: no almacena en caché en la primera visita y puede causar problemas al manejar múltiples estados, ya que solo guarda el estado inicial.

Método 2: Uso de atributos include/exclude y el gancho beforeRouteEnter

Los atributos include y exclude en keep-alive permiten especificar qué componentes se almacenan en caché. Se pueden usar cadenas separadas por comas, expresiones regulares o matrices.

<keep-alive include="inicio,catalogo,busqueda">
  <router-view></router-view>
</keep-alive>

El atributo max (disponible desde Vue 2.5.0) limita el número máximo de instancias en caché.

<keep-alive :max="10">
  <component :is="vista"></component>
</keep-alive>

Los componentes dentro de keep-alive acceden a los ganchos de ciclo de vida activated y deactivated.

  • activated: Se llama cuando el componente se activa, después de mounted en la primera renderización y al reactivarse.
  • deactivated: Se llama cuando el componente se desactiva, como alternativa a beforeDestroy.

En la práctica, se puede usar beforeRouteEnter para inicializar datos cuendo es necesario, por ejemplo, al no provenir de una ruta específica.

beforeRouteEnter(hacia, desde, siguiente) {
  siguiente(instancia => {
    if (desde.path !== '/detalle_producto') {
      instancia.titulo = hacia.query.nombre
      instancia.categoriaSuperior = hacia.query.categoriaSuperior
      instancia.items = []
      instancia.pagina = 1
      instancia.indiceCategoria = 0
      instancia.esBusqueda = false
      instancia.obtenerCategorias()
    }
  })
}

Este método requiere reinicializar datos manualmente, lo que puede ser propenso a errores.

Método 3: Uso de Vuex y el gancho beforeRouteLeave (recomendado)

Este enfoque utiliza Vuex para gestionar dinámicamente los componentes que se almacenan en caché.

1. Configurar scrollBehavior como en el Método 1.

2. Usar keep-alive con una lista reactiva de componentes desde Vuex.

<keep-alive :include="componentesEnCache">
  <router-view></router-view>
</keep-alive>

3. En el store de Vuex, definir el estado y las mutaciones para gestionar los componentes en caché.

const store = new Vuex.Store({
  state: {
    componentesEnCache: []
  },
  mutations: {
    ACTUALIZAR_COMPONENTES_CACHE(estado, lista) {
      estado.componentesEnCache = lista
    }
  }
})

4. En el gancho beforeRouteLeave del componente, controlar qué componentes se almacenan en caché basado en la navegación.

beforeRouteLeave(hacia, desde, siguiente) {
  this.ocupado = true
  if (hacia.path === '/detalle_producto') {
    this.$store.commit('ACTUALIZAR_COMPONENTES_CACHE', ['inicio'])
  } else {
    this.$store.commit('ACTUALIZAR_COMPONENTES_CACHE', [])
  }
  siguiente()
}

Adicionalmente, para manejar cambios en los parámetros de la misma ruta, se puede usarr un watcher en la propiedad $route.

observar: {
  '$route'(hacia, desde) {
    document.title = hacia.query.nombre
    this.obtenerDatos()
  }
}

Etiquetas: vue.js Keep-Alive vuex vue-router JavaScript

Publicado el 6-11 00:49