Implementación de navegación con refresco hacia adelante y caché hacia atrás en Vue.js

En aplicaciones Vue.js, a menudo necesitamos implementar comportamientos específicos de navegación:

  1. Al navegar desde una página de búsqueda a una página de resultados, los resultados deben actualizarse con datos frescos.
  2. Al regresar de una página de detalle a la lista de resultados, debemos mantener los datos cargados previamente y restaurar la posición de desplazamiento.

Para lograr esto, utilizaremos el componente keep-alive proporcionado por Vue 2. Primero, en nuestro archivo app.vue, definimos keep-alive:

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

Esta configuración utiliza el campo keepAlive personalizado en meta información de la ruta para determinar si el componente debe ser caché.

En nuestro archivo router/index.js, definimos la meta información:

{
  path: '/lista',
  name: 'ListaResultados',
  component: resolve => require(['@/paginas/lista'], resolve),
  meta: {
    necesitaRefresco: false,
    keepAlive: true
  }
}

Antes de implementar la lógica de refresco o caché, revisemos los hooks de ciclo de vida relacionados con el caché:

Para componentes con keep-alive:

  • Primera entrada: beforeRouteEnter -> created -> ... -> activated -> ... -> deactivated
  • Entradas posteriores: beforeRouteEnter -> activated -> deactivated

El hook activated se ejecuta cada vez que el componente activado desde el caché. Implementemos nuesttra lógica:

activated() {
  // Solo refrescar datos si no se debe usar caché
  if(!this.$route.meta.necesitaRefresco) {
    this.datosLista = []; // Limpiar datos existentes
    this.cargarDatos(); // Función para obtener datos
  } else {
    this.$route.meta.necesitaRefresco = false;
  }
}

En la página de detalle, usamos el hook beforeRouteLeave:

beforeRouteLeave(to, from, next) {
  if (to.name == 'ListaResultados') {
    to.meta.necesitaRefresco = true;
  }
  next();
}

Para manejar el caso donde navegamos a una página diferente que no es detalle y regresamos sin refrescra:

beforeRouteLeave(to, from, next) {
  if (to.name == 'ListaResultados') {
    to.meta.necesitaRefresco = true;
  }
  next();
}

Para escenarios más complejos, como eliminar un elemento en la página de detalle que requiere refrescar la lista al regresar:

data() {
  return {
    elementoEliminado: false
  }
},
beforeRouteLeave(to, from, next) {
  if (to.name == 'ListaResultados') {
    to.meta.necesitaRefresco = this.elementoEliminado;
  }
  next();
},
methods: {
  eliminarElemento() {
    // Lógica de eliminación
    this.elementoEliminado = true;
    this.$router.go(-1);
  }
}

Finalmente, para manejar la posición de scroll:

scrollBehavior(to, from, savedPosition) {
  if (savedPosition) {
    return savedPosition;
  } else {
    if (from.meta.keepAlive) {
      from.meta.posicionGuardada = document.body.scrollTop;
    }
    return { x: 0, y: to.meta.posicionGuardada || 0 };
  }
}

Etiquetas: vue.js Keep-Alive enrutamiento caché de componentes manejo de scroll

Publicado el 6-6 23:39