Gestión de navegación y ciclo de vida de vistas en aplicaciones uni-app

Fundamentos del motor de enrutamiento

El subsistema de rutas en uni-app opera sobre una estructura tipo pila (LIFO). Cada interacción de interfaz modifica esta colección de vistas según reglas estrictas. Seleccionar la API correcta garantiza un comportamiento predecible del historial de pantallas y evita fugas de memoria o transiciones rotas.

Referencia rápida de métodos nativos

Método Efecto en la pila Preserva la vista origen Soporte para TabBar Pasaje de datos
uni.navigateTo Añade un nivel (+1) Sí No permitido Vía cadena de consulta
uni.redirectTo Reemplaza el nivel actual (0 cambios netos) No No permitido Vía cadena de consulta
uni.reLaunch Vacía toda la colección (reseteo total) No Permitido Vía cadena de consulta
uni.switchTab Descarta rutas intermedias, activa la pestaña definida No Exclusivo Requiere almacén global o bus de eventos
uni.navigateBack Retira n niveles (-n) - - No nativo (usar patrón publish/subscribe)

Implementación y casos de uso

Desplazamiento preservando contexto

uni.navigateTo empuja una nueva ruta sobre la pila. Es el estándar para formularios secuenciales, módulos de detalle o cualquier flujo que exija retroceso inmediato. La pila tiene un límite operativo de diez elementos; superar este umbral genera descarte automático del registro más antiguo.


const iniciarProceso = async (targetId) => {
 try {
   await uni.navigateTo({
     url: `/workflows/step-one?ref=${encodeURIComponent(targetId)}&stage=pending`
   });
 } catch (error) {
   console.error('Fallo en la navegación:', error.errMsg);
 }
};
// Captura en la vista destino
onLoad(queryParams) {
 this.referenceId = queryParams.ref;
 this.stageStatus = queryParams.stage;
}
 

Sustitución de ruta actual

uni.redirectTo elimina la página padre antes de renderizar la siguiente. Resulta idóneo cuando la experiencia no debe permitir volver atrás, como en flujos de checkout finalizados o autenticaciones exitosas. El contador de profundidad permanece inalterado.


const actualizarDestino = () => {
 uni.redirectTo({
   url: '/modules/success-report',
   complete: () => console.log('Entorno sustituido correctamente')
 });
};
 

Reseteo completo de vistas

uni.reLaunch destruye la pila existente y carga una ruta absoluta. Es crucial para cerrar sesiones, reconfigurar el entorno de desarrollo o garantizar que la aplicación arranque desde un estado limpio. Admite parámetros en la URI aunque borra todo el historial acumulado.


const reiniciarSesion = () => {
 uni.reLaunch({
   url: '/auth/welcome-screen'
 });
};
 

Activación de pestañas inferiores

La única vía oficial para interactuar con rutas marcadas como TabBar es uni.switchTab. Internamente, cierra automáticamente todas las capas no pertenecientes a la barra principal y fuerza la reconstrucción de la pestaña seleccionada. Su diseño excluye la transmisión directa mediante url; los valores de consulta son ignorados por el compilador.


const activarPestañaCentral = () => {
 uni.switchTab({ url: '/tabs/main-dashboard' });
};
 

Retroceso controlado

uni.navigateBack opera sobre la pila mediante un desplazador numérico. Si el valor supera los registros disponibles, la aplicación salta silenciosamente a la ruta raíz. Importante: la ejecución de este método dispara el gancho onShow en la página recuperada, facilitando oepraciones de actualización sin necesidad de recargas manuales.


const avanzarRetroceso = (escalones = 1) => {
 uni.navigateBack({ delta: escalones });
};
// Sincronización automática en vista restaurada
onShow() {
 this.obtenerRegistrosActualizados();
}
 

Gestión avanzada de estado cruzado

Utilidad de enrutamiento inteligente

Aislamos la lógica de detección de rutas y codificación de parámetros en un gestor centralizado. Este enfoque automatiza la selección de API según la naturaleza de la dirección destino.


class PathManager {
 constructor(tabBarRoutes) {
   this.exclusiveRoutes = tabBarRoutes;
 }

 navegarA(ruta, opciones = {}) {
   const esPestaña = this.exclusiveRoutes.includes(ruta);
   const cadenaConsulta = this.formatearQuery(opciones);
   const target = `${ruta}${cadenaConsulta}`;

   if (esPestaña) {
     this.transmitirDatos(opciones);
     uni.switchTab({ url: ruta });
   } else {
     uni.navigateTo({ url: target });
   }
 }

 formatearQuery(pares) {
   const entries = Object.entries(pares);
   if (!entries.length) return '';
   const segments = entries.map(([k, v]) => `${k}=${encodeURIComponent(v)}`);
   return `?${segments.join('&')}`;
 }

 transmitirDatos(payload) {
   uni.$emit('datosPestaña', payload);
 }
}

export default new PathManager(['/tabs/home', '/tabs/profile']);
 

Sincronización persistente para TabBar

Dado que switchTab desecha la pila intermedia, el almacenamiento local de instancia o variables globales resultan insuficientes si la aplicación sufre GC agresivo. Un módulo Vuex dedicado mantiene contratos seguros entre pantallas independientes.


// store/modules/route-sync.js
export default {
 namespaced: true,
 state: () => ({
   contextoSesión: null,
   flagRecargaContenido: false
 }),
 mutations: {
   vincularContexto(state, info) {
     state.contextoSesión = info;
   },
   solicitarRefresco(state, activo) {
     state.flagRecargaContenido = activo;
   }
 },
 actions: {
   sincronizarYmover({ commit }, ruta, cargaÚtil) {
     if (cargaÚtil) {
       commit('vincularContexto', cargaÚtil);
       commit('solicitarRefresco', true);
     }
     uni.switchTab({ url: ruta });
   }
 }
};

// Consumo en origen
this.$store.dispatch('route-sync/sincronizarYmover', '/tabs/reports', { filtroMes: '11' });
 

Observabilidad y diagnóstico de rutas

Monitorear la pila activa previene errores como colapsos por saturación de memoria o redirecciones bloqueadas. El objeto getCurrentPages() expone metadatos de cada nodo registrado.


const inspeccionarPila = () => {
 const nodos = getCurrentPages();
 console.group('Topología de vistas');
 console.log(`Profundidad total: ${nodos.length}`);
 console.log(`Vista superior: ${nodos[nodos.length - 1]?.route ?? 'vacía'}`);
 console.log(`Predecesora: ${nodos[nodos.length - 2]?.route ?? 'inválida'}`);
 console.groupEnd();
};

// Instrumentación a nivel de aplicación
Page({
 onHide() { console.warn('Aplicación suspendida o cambiada de foco'); },
 onShow() { inspeccionarPila(); }
});
 

Prevención de activaciones redundantes

Los gestos táctiles accidentales pueden disparar múltiples solicitudes simultáneas. Un mecanismo de anti-rebote a nivel modular garantiza intervalos mínimos entre transiciones críticas.


let temporizadorBloqueo = null;
const ACCESO_SEGURIDAD = 600; // milisegundos

const navegarConCautela = (destino) => {
 const ahora = Date.now();
 if (temporizadorBloqueo && (ahora - temporizadorBloqueo) < ACCESO_SEGURIDAD) {
   console.debug('Transacción ignorada por ventana de seguridad');
   return;
 }
 temporizadorBloqueo = ahora;
 uni.navigateTo({ url: destino });
};
 

Mapeo de errores frecuentes

  • fail can not switch to a tabBar page: Ocurre al usar navigateTo o redirectTo sobre rutas declaradas como pestañas. La corrección implica derivar automáticamente a switchTab.
  • fail page limit exceeded: Indica saturación de los diez niveles permitidos. Mitigaciones: emplear redirectTo para substituir, invocar reLaunch para purgar, o retroceder explícitamente antes de avanzar.
  • Pérdida de parámetros en pestañas: Las URIs enviadas a switchTab se truncan. Migrar obligatoriamente a inyección vía $emit, estados Vuex o variables persistentes en getApp().globalData.

Etiquetas: uni-app ruteo-móvil pila-de-navegación switchTab navigateTo

Publicado el 10-20 03:02