🧭 3.5 Navigation dans une application Ionic-Vue

  • La navigation est un pilier d’une app mobile

  • On travaille avec :

    • des Ă©crans
    • des piles de navigation
    • des transitions animĂ©es
  • Ionic-Vue s’appuie sur Vue Router + une couche Ionic

    • pour garantir une expĂ©rience native sur Android / iOS

🎯 Objectifs d'apprentissage

À la fin du chapitre, vous serez capables de :

  • Expliquer navigation linĂ©aire vs non-linĂ©aire

  • Expliquer le rĂŽle de Vue Router dans Ionic-Vue

  • Structurer un router adaptĂ© au mobile

  • ImplĂ©menter les patterns courants :

    • Stack, Tabs, Menu
  • Naviguer avec / sans paramĂštres

  • ContrĂŽler :

    • les transitions
    • le bouton retour
  • Éviter les erreurs classiques de navigation hybride

🌐 Web vs đŸ“± Mobile

Pourquoi la navigation est différente ?

Web classique :

  • Navigation basĂ©e sur les URLs
  • Historique linĂ©aire
  • Bouton retour = page prĂ©cĂ©dente

Mobile :

  • Logique d’écrans

  • Organisation en piles (stacks)

  • Transitions animĂ©es natives

  • Bouton retour matĂ©riel / gestuel

  • Comportement cohĂ©rent avec :

    • iOS (swipe back)
    • Android (back button)

👉 Ionic adopte une logique mobile-first, mĂȘme avec Vue Router dessous.

🧠 3.5.1 Principe gĂ©nĂ©ral

Vue Router vs Ionic

Vue Router décide :

  • oĂč l’app doit naviguer
  • DĂ©finition des routes
  • Gestion des URLs
  • Passage de paramĂštres
  • Navigation programmĂ©e : router.push(), router.replace(), etc.

Rîle d’Ionic (IonRouterOutlet)

Ionic décide :

  • comment la navigation est vĂ©cue par l’utilisateur
  • Gestion de la pile de navigation
  • Transitions animĂ©es natives
  • Bouton retour Android
  • Swipe back iOS
  • Conservation de l’état des pages

<IonRouterOutlet> :

  • remplace le <router-view /> classique
  • permet Ă  Ionic de contrĂŽler le cycle de vie des pages

À retenir

Vue Router dĂ©cide oĂč aller. Ionic dĂ©cide comment on y va.

đŸ—ș 3.5.2 Navigation linĂ©aire vs non-linĂ©aire

Navigation linéaire (Linear routing)

  • Parcours sĂ©quentiel : Ă©cran aprĂšs Ă©cran
  • Les Ă©crans sont empilĂ©s dans une stack
  • Le bouton retour revient Ă  l’écran prĂ©cĂ©dent
  • Chemin souvent unique

Navigation linĂ©aire – Exemple

Exemples typiques :

  • Onboarding :

    • Accueil → PrĂ©sentation → Inscription
  • Formulaire multi-Ă©tapes :

    • Infos perso → Adresse → Paiement
  • Liste → DĂ©tail → Édition

En Ionic :

  • ion-router-outlet gĂšre la pile
  • router.push() pour avancer
  • Bouton retour (Android / iOS) pour revenir

👉 C’est la forme la plus proche du comportement natif.

Limite de la navigation linéaire

  • Ne gĂšre pas bien les expĂ©riences plus complexes :

    • onglets (Tabs)
    • sections parallĂšles
  • Difficile Ă  utiliser pour des UIs avec plusieurs sections principales

C’est lĂ  que la navigation non-linĂ©aire intervient.

Navigation non-linéaire (Non-linear routing)

  • L’utilisateur ne suit pas un chemin unique
  • Peut changer de section Ă  tout moment
  • Chaque section a sa propre pile d’écrans
  • Le bouton retour reste dans la section courante

Exemple non-linéaire (Tabs)

Scénario (simplifié) :

  1. Onglet Originals
  2. On ouvre la vue Ted Lasso
  3. On change d’onglet → Search
  4. On revient sur Originals → on revoit Ted Lasso
  5. Le bouton retour ramĂšne Ă  Originals (liste), pas Ă  Search

Pourquoi ?

  • Chaque onglet est une pile indĂ©pendante
  • Le bouton retour ne change pas de tab, il remonte la pile de cet onglet

Attention Ă  router.go(-1)

  • En non-linĂ©aire, router.go(-1) peut :

    • revenir Ă  une mauvaise page
    • casser la logique des piles par onglet
  • Les APIs type router.go() sont faites pour un historique linĂ©aire

👉 Avec Ionic + Tabs → il faut laisser Ionic gĂ©rer la pile.

SynthÚse : linéaire vs non-linéaire

Navigation linéaire

  • Stack unique
  • Retour = page prĂ©cĂ©dente
  • Flux simples / guidĂ©s

Navigation non-linéaire

  • Plusieurs stacks (par onglet, par menu)
  • Retour reste dans la stack courante
  • Flux complexes, multi-sections

Quel pattern pour quel usage ?

Pattern Type Usage recommandé
Stack Linéaire Détails, formulaires, parcours guidés
Tabs Non-linĂ©aire Sections principales de l’application
Menu Non-linéaire Sections secondaires / navigation globale

On peut combiner les patterns, mais il faut garder une logique claire.

📁 3.5.3 Structure du router Ionic-Vue

Fichier principal

  • Configuration dans : src/router/index.ts

  • On utilise :

    • createRouter
    • createWebHistory
    • RouteRecordRaw

Exemple avec Tabs

// src/router/index.ts
import { createRouter, createWebHistory } from '@ionic/vue-router'
import type { RouteRecordRaw } from 'vue-router'

const routes: RouteRecordRaw[] = [
  {
    path: '/',
    redirect: '/tabs/home'
  },
  {
    path: '/tabs/',
    component: () => import('@/views/TabsPage.vue'),
    children: [
      {
        path: 'home',
        component: () => import('@/views/HomePage.vue')
      },
      {
        path: 'settings',
        component: () => import('@/views/SettingsPage.vue')
      }
    ]
  }
]

const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes
})

export default router

Bonnes pratiques router

  • DĂ©finir un point d’entrĂ©e clair (redirect)

  • Utiliser le lazy loading :

    • () => import('...')
  • Laisser IonRouterOutlet gĂ©rer :

    • pile d’écrans
    • animations
    • Ă©tat des pages

📑 3.5.4 Navigation par onglets (Tabs)

Composants utilisés

  • ion-tabs : conteneur des onglets
  • ion-tab-bar : barre d’onglets (souvent en bas)
  • ion-tab-button : bouton d’onglet
  • ion-router-outlet : zone qui change selon la route

Exemple Tabs

<template>
  <ion-tabs>
    <ion-router-outlet />

    <ion-tab-bar slot="bottom">
      <ion-tab-button tab="home" href="/tabs/home">
        <ion-label>Accueil</ion-label>
      </ion-tab-button>

      <ion-tab-button tab="settings" href="/tabs/settings">
        <ion-label>ParamĂštres</ion-label>
      </ion-tab-button>
    </ion-tab-bar>
  </ion-tabs>
</template>

Comportement des Tabs

  • Chaque onglet a sa propre stack

  • Changer d’onglet ne vide pas l’historique

  • Le bouton retour :

    • reste dans l’onglet courant
    • remonte l’historique de cet onglet

🔁 3.5.5 Navigation entre pages (Stack)

Navigation programmée (Vue Router)

import { useRouter } from 'vue-router'

const router = useRouter()

function goToDetails () {
  router.push('/details')
}

Navigation déclarative (router-link)

<ion-button router-link="/details">
  Voir détails
</ion-button>

Avantages :

  • Simple
  • Lisible

Limites :

  • Pas de logique avant la navigation :

    • pas de validation de formulaire
    • pas de confirmation

🧠 3.5.6 useIonRouter – Navigation avancĂ©e

Pourquoi useIonRouter ?

  • router-link :

    • ne permet pas d’exĂ©cuter du code avant navigation
  • router.push seul :

    • ne contrĂŽle pas les animations Ionic

useIonRouter combine :

  • la navigation programmĂ©e
  • avec le contrĂŽle des transitions mobiles

Exemple useIonRouter

import { useIonRouter } from '@ionic/vue'

const ionRouter = useIonRouter()

function goToDetails () {
  // ex : valider un formulaire avant
  ionRouter.push('/details', 'forward')
}
  • 2ᔉ paramĂštre = direction :

    • 'forward'
    • 'back'
    • 'root'

👉 Permet de rester cohĂ©rent avec les animations natives (push / pop).

📜 3.5.7 Passage de paramùtres

Route paramétrée

{
  path: '/notes/:id',
  component: () => import('@/views/NoteDetailPage.vue')
}

Navigation avec paramĂštre

router.push(`/notes/${note.id}`)

Récupération du paramÚtre

import { useRoute } from 'vue-router'

const route = useRoute()
const noteId = route.params.id

On peut ensuite charger la note correspondante (API, store, etc.).

🔙 3.5.8 Retour & transitions

Gestion automatique par Ionic

  • Bouton retour Android
  • Swipe back iOS
  • Transitions cohĂ©rentes avec la plateforme

Bouton retour dans le header

<ion-header>
  <ion-toolbar>
    <ion-buttons slot="start">
      <ion-back-button default-href="/tabs/home" />
    </ion-buttons>
    <ion-title>Détail</ion-title>
  </ion-toolbar>
</ion-header>
  • default-href : route utilisĂ©e si la pile est vide

À Ă©viter absolument

  • window.history.back()
  • router.go(-1)

Pourquoi ?

  • Contournent la pile Ionic

  • Peuvent provoquer des retours :

    • vers le mauvais onglet
    • vers des Ă©crans inactifs

👉 Toujours laisser Ionic gĂ©rer la navigation mobile.

📋 3.5.9 Menu latĂ©ral (Side Menu)

Exemple simple

<ion-menu content-id="main-content">
  <ion-header>
    <ion-toolbar>
      <ion-title>Menu</ion-title>
    </ion-toolbar>
  </ion-header>

  <ion-content>
    <ion-list>
      <ion-item router-link="/tabs/home">Accueil</ion-item>
      <ion-item router-link="/tabs/settings">ParamĂštres</ion-item>
    </ion-list>
  </ion-content>
</ion-menu>

<ion-router-outlet id="main-content" />

Side Menu – Remarques

  • Utile pour :

    • sections secondaires
    • navigation globale
  • À Ă©viter :

    • combiner Tabs + Menu sans logique claire
  • Attention Ă  :

    • ne pas multiplier les patterns dans tous les sens

đŸ› ïž 3.5.10 Bonnes pratiques & erreurs

Bonnes pratiques

  • Penser mobile-first

  • Choisir un pattern principal :

    • Tabs ou Menu ou Stack
  • Laisser Ionic gĂ©rer :

    • la pile
    • les transitions
    • le retour

Erreurs fréquentes

  • MĂ©langer :

    • Tabs + Menu + navigations custom
  • Manipuler manuellement l’historique

  • Utiliser uniquement la logique “web” :

    • raisonner en URL
    • oublier la notion de stack mobile
  • Utiliser router.go(-1) dans un contexte Tabs

đŸ§Ș 3.5.11 ActivitĂ© pratique

Mini flow de navigation

Objectifs :

  1. Créer une page Liste (ex : liste de notes / tùches)

  2. Créer une page Détail

  3. Mettre en place la navigation :

    • Liste → DĂ©tail avec un paramĂštre (id)
  4. Ajouter un bouton retour fonctionnel

  5. Tester :

    • dans le navigateur (ionic serve)
    • sur Ă©mulateur / tĂ©lĂ©phone si possible

Bonus : utiliser useIonRouter pour contrĂŽler les transitions.