Navegación en proyectos Ionic: Cómo moverse fácilmente entre vistas

Navegación en proyectos Ionic: Cómo moverse fácilmente entre vistas

¿Qué tipos de navegaciones existen en Ionic?

Existen diferentes tipos de patrones de navegación como:

  • Push y Pop
  • Tabs
  • Side Drawers

Al final del tutorial vamos a poder navegar a través de diferentes secciones de una nueva aplicación.

Preparación del proyecto

Creamos un nuevo proyecto en blanco como lo hicimos anteriormente y eliminamos todos los archivos innecesarios como ya se ha explicado anteriormente.

Instalamos las librerías necesarias.

$ yarn

Arrancamos el proyecto.

$ ionic serve

Ahora que ya tenemos nuestra aplicación ejecutándose podemos continuar con el proyecto.

Creamos el directorio src/pages que es donde vamos a almacenar nuestras páginas.

Una página a diferencia de un componente consta de una dirección url.

Creamos una nueva pagina src/pages/Cursos.tsx que va a tener un listado de cursos.

import React from "react";
import { IonHeader, IonTitle, IonContent } from "@ionic/react";

const Cursos: React.FC = () => {
    return (
        <React.Fragment>
            <IonHeader>
                <IonTitle>Cursos</IonTitle>
            </IonHeader>
            <IonContent>
                <h2>Este es el contenido</h2>
            </IonContent>
        </React.Fragment>
    );
};

export default Cursos;

¿Cómo utilizar un router dentro de Ionic?

El router de Ionic esta basado en ReactRouter pero a diferencia de este contiene una serie de animaciones entre una ruta y otra, esto permite transiciones mas fluidas entre una página (ruta) y otra.

Abrimos App.tsx y dentro de este importamos el router de Ionic.

import React from "react";
import { IonApp } from "@ionic/react";
import { Route } from "react-router-dom";
import { IonReactRouter } from "@ionic/react-router";

El componente Route nos permite crear rutas, todas estas dentro del router IonRouter.

Importamos también nuestra página de inicio, que en este caso es Cursos.tsx.

const App: React.FC = () => (
    <IonApp>
        <IonReactRouter>
            <Route path="/" exact>
                <Cursos />
            </Route>
        </IonReactRouter>
    </IonApp>
);

Nuestra aplicación debe mostrar ahora el contenido de Cursos.tsx.

¿Cómo trabajar con múltiples rutas en Ionic?

Ahora vamos a crear la pagina src/pages/Objetivos.tsx.

import React from "react";
import { IonHeader, IonToolbar, IonTitle, IonContent } from "@ionic/react";

const Objetivos: React.FC = () => {
    return (
        <React.Fragment>
            <IonHeader>
                <IonToolbar>Objetivos del Curso</IonToolbar>
            </IonHeader>
            <IonContent>
                <h2>Este es el objetivo del curso</h2>
            </IonContent>
        </React.Fragment>
    );
};

export default Objetivos;

E implementamos este componente sobre su correspondiente ruta.

const App: React.FC = () => (
    <IonApp>
        <IonReactRouter>
            <Route path="/" exact>
                <Cursos />
            </Route>
            <Route path="/objetivos">
                <Objetivos />
            </Route>
        </IonReactRouter>
    </IonApp>
);

En este punto si accedemos a la url del proyecto “/objetivos” debemos poder ver el contenido de nuestra pagina pages/Objetivos.tsx.

Ahora vamos a complementar nuestro ejemplo agregando un link a la ruta /objetivos, para ello abrimos la página Cursos.tsx y agregamos un botón que haga referencia a esta.

import React from "react";
import { IonHeader, IonTitle, IonContent, IonButton } from "@ionic/react";

const Cursos: React.FC = () => {
    return (
        <React.Fragment>
            <IonHeader>
                <IonTitle>Cursos</IonTitle>
            </IonHeader>
            <IonContent>
                <h2>Este es el contenido</h2>
                <IonButton routerLink="/objetivos">
                    Ir a los objetivos
                </IonButton>
            </IonContent>
        </React.Fragment>
    );
};

export default Cursos;

Si actualizamos el proyecto vamos a encontrar que aparece un botón el cual al dar clics nos lleva a la página de los objetivos de los cursos.

¿Cómo realizar transiciones entre paginas en Ionic?

Cada una de las páginas que hemos venido utilizando <React.Fragment> para incluir el contenido de las páginas. Si bien podemos movernos entre una página y otra la transición esperada no es visible.

Primero vamos a encerrar las rutas dentro de <IonRouterOutlet> que se encuentra disponible dentro del paquete @ionic/react;

import { IonApp, IonRouterOutlet } from '@ionic/react';
.
.
.
const App: React.FC = () => (
    <IonApp>
        <IonReactRouter>
            <IonRouterOutlet>
                <Route path="/" exact>
                    <Cursos />
                </Route>
                <Route path="/objetivos">
                    <Objetivos />
                </Route>
            </IonRouterOutlet>
        </IonReactRouter>
    </IonApp>
);

<IonRouterOutlet>
    <Route path="/" exact>
        <Cursos />
    </Route>
    <Route path="/objetivos">
        <Objetivos />
    </Route>
</IonRouterOutlet>

export default App;

También reemplazamos las referencias a <React.Fragment> por <IonApp> tanto en Cursos.tsx como en Objetivos.tsx.

import React from "react";
import {
    IonHeader,
    IonTitle,
    IonContent,
    IonButton,
    IonPage,
} from "@ionic/react";

const Cursos: React.FC = () => {
    return (
        <IonPage>
            <IonHeader>
                <IonTitle>Cursos</IonTitle>
            </IonHeader>
            <IonContent>
                <h2>Este es el contenido</h2>
                <IonButton routerLink="/objetivos">
                    Ir a los objetivos
                </IonButton>
            </IonContent>
        </IonPage>
    );
};

export default Cursos;
import React from "react";
import {
    IonHeader,
    IonTitle,
    IonContent,
    IonButton,
    IonPage,
} from "@ionic/react";

const Cursos: React.FC = () => {
    return (
        <IonPage>
            <IonHeader>
                <IonTitle>Cursos</IonTitle>
            </IonHeader>
            <IonContent>
                <h2>Este es el contenido</h2>
                <IonButton routerLink="/objetivos">
                    Ir a los objetivos
                </IonButton>
            </IonContent>
        </IonPage>
    );
};

export default Cursos;
import React from "react";
import {
    IonHeader,
    IonToolbar,
    IonTitle,
    IonContent,
    IonPage,
} from "@ionic/react";

const Objetivos: React.FC = () => {
    return (
        <IonPage>
            <IonHeader>
                <IonToolbar>Objetivos del Curso</IonToolbar>
            </IonHeader>
            <IonContent>
                <h2>Este es el objetivo del curso</h2>
            </IonContent>
        </IonPage>
    );
};

export default Objetivos;

¿Cómo agregar un botón para volver atrás en Ionic?

Ahora que ya tenemos los primeros elementos de nuestra navegación, vamos a agregar un botón que nos permita navegar hacia atrás en el historial. Para ello vamos a actualizar nuestra <IonToolbar> dentro de Objetivos.tsx con un botón <IonBackButton> contenido dentro de <IonButtons>.

import React from "react";
import {
    IonHeader,
    IonToolbar,
    IonTitle,
    IonContent,
    IonPage,
    IonButtons,
    IonBackButton,
} from "@ionic/react";

const Objetivos: React.FC = () => {
    return (
        <IonPage>
            <IonHeader>
                <IonToolbar>
                    <IonButtons slot="start">
                        <IonBackButton defaultHref="/" />
                    </IonButtons>
                    <IonTitle>Objetivos del Curso</IonTitle>
                </IonToolbar>
            </IonHeader>
            <IonContent>
                <h2>Este es el objetivo del curso</h2>
            </IonContent>
        </IonPage>
    );
};

export default Objetivos;

La propiedad defaultHref permite definir un punto a donde ir cuando se refresca o se accede directamente a la página y el historial no tiene un punto de referencia a donde regresar.

¿Cómo utilizar las tabs en Ionic?

Las tabs en un proyecto React en Ionic se crean utilizando el componente <IonTabBar>. Este se combina con otros como <IonTabButton>.

Abrimos el archivo App.tsx y englobamos el IonRouterOutlet dentro de IonTabs.

import { IonApp, IonRouterOutlet, IonTabBar, IonTabButton, IonLabel, IonIcon, IonTabs } from '@ionic/react';
.
.
.
const App: React.FC = () => (
    <IonApp>
        <IonReactRouter>
            <IonTabs>
                <IonRouterOutlet>
                    <Route path="/cursos" exact>
                        <Cursos />
                    </Route>
                    <Route path="/objetivos">
                        <Objetivos />
                    </Route>
                    <Redirect to="/cursos" />
                </IonRouterOutlet>
                <IonTabBar slot="bottom">
                    <IonTabButton tab="a" href="/objetivos">
                        <IonLabel>Objetivos</IonLabel>
                    </IonTabButton>
                    <IonTabButton tab="b" href="/cursos">
                        <IonLabel>Cursos</IonLabel>
                    </IonTabButton>
                </IonTabBar>
            </IonTabs>
        </IonReactRouter>
    </IonApp>
);

Ahora al abrir la aplicación podemos ver la tabs en la parte inferior con dos botones, el de Objetivos y el de Cursos, ambos se preservan a través de toda la aplicación.

Para indicar a donde deben ir cada uno de los links, es necesario utilizar el parámetro href de IonTavButton, de igual forma es necesario asignar un valor único a la propiedad tab para cada uno de estos botones.

¿Cómo configurar los estilos de los componentes de navegación en Ionic?

Ya hablamos anteriormente de que es posible generar una paleta de colores desde el Color Generator de Ionic en donde es posible personalizar una paleta de colores y sustituir el archivo de configuración original variables.css.

Si deseáramos configurar un valor específico de nuestro componente de navegación podríamos sobrescribir nuestros propios estilos.

:root {
    --ion-toolbar-background: var(--ion-color-primary);
    --ion-tab-bar-background: var(--ion-color-primary);
    --ion-tab-bar-color-selected: var(--ion-color-secondary);
}

Agregar mas contenido para navegar

Podemos agregar un listado de cursos dentro de Cursos.tsx.

export const CURSOS_DATA = [
    { id: "c1", titulo: "Titulo 1" },
    { id: "c2", titulo: "Titulo 2" },
    { id: "c3", titulo: "Titulo 3" },
];

Dentro del mismo archivo actualizamos el loop para generar la lista de cursos.

<IonGrid>
    {CURSOS_DATA.map((curso) => {
        return (
            <IonRow>
                <IonCol>
                    <IonCard>
                        <IonCardContent className="ion-text-center">
                            <h2>{curso.titulo}</h2>
                            <IonButton routerLink={`/curso/${curso.id}`}>
                                Ver Información
                            </IonButton>
                        </IonCardContent>
                    </IonCard>
                </IonCol>
            </IonRow>
        );
    })}
</IonGrid>

Mediante map podemos hacer la iteración del arreglo CURSOS_DATA.

Para listar el objetivo de un curso creamos un componente exclusivo para esto.

import React from "react";
import {
    IonHeader,
    IonToolbar,
    IonTitle,
    IonContent,
    IonPage,
    IonButtons,
    IonBackButton,
} from "@ionic/react";
import { useParams } from "react-router-dom";
import { CURSOS_DATA } from "./Cursos";

const Objetivos: React.FC = () => {
    const { id } = useParams<{ id: string }>();

    const curso = CURSOS_DATA.find((c) => c.id === id);

    return (
        <IonPage>
            <IonHeader>
                <IonToolbar>
                    <IonButtons slot="start">
                        <IonBackButton defaultHref="/" />
                    </IonButtons>
                    <IonTitle>
                        {curso ? curso.titulo : "Curso no encontrado"}
                    </IonTitle>
                </IonToolbar>
            </IonHeader>
            <IonContent>
                <h2>Este es el objetivo del curso</h2>
            </IonContent>
        </IonPage>
    );
};

export default Objetivos;

Para poder localizar el curso a mostrar requerimos importar el arreglo CURSOS_DATA y utilizar useParams que forma parte de react-router-dom.

Finalmente para implementar las rutas tenemos que actualizar el router en App.tsx.

const App: React.FC = () => (
    <IonApp>
        <IonReactRouter>
            <IonTabs>
                <IonRouterOutlet>
                    <Route path="/cursos" exact>
                        <Cursos />
                    </Route>
                    <Route path="/objetivos" exact>
                        <Objetivos />
                    </Route>
                    <Route path="/curso/:id">
                        <Objetivo />
                    </Route>
                    <Redirect to="/cursos" />
                </IonRouterOutlet>
                <IonTabBar slot="bottom">
                    <IonTabButton tab="a" href="/objetivos">
                        <IonLabel>Objetivos</IonLabel>
                    </IonTabButton>
                    <IonTabButton tab="b" href="/cursos">
                        <IonLabel>Cursos</IonLabel>
                    </IonTabButton>
                </IonTabBar>
            </IonTabs>
        </IonReactRouter>
    </IonApp>
);

¿Cómo agregar un menú desplegable para móvil en Ionic?

Vamos a echar un vistazo al side menu, para ello vamos a crear un nuevo componente que se encargue de realizar un filtrado.

Primero vamos a crear un nuevo componente pages/Filtrado.tsx para propósitos de filtrado.

import React from "react";
import {
    IonPage,
    IonHeader,
    IonToolbar,
    IonTitle,
    IonContent,
    IonButtons,
    IonMenuButton,
} from "@ionic/react";

const Filter: React.FC = () => {
    return (
        <IonPage>
            <IonHeader>
                <IonToolbar>
                    <IonButtons slot="start">
                        <IonMenuButton />
                    </IonButtons>
                    <IonTitle>Filtrado</IonTitle>
                </IonToolbar>
            </IonHeader>
            <IonContent>
                <h2>Contenido Aquí!</h2>
            </IonContent>
        </IonPage>
    );
};

export default Filter;

Para poder crear un menú desplegable (side menu) lo primero que tenemos que hacer es preparar el contenido de nuestro menú, esto lo podemos hacer directamente en el router mediante IonMenu y asociamos cada uno de sus botones dentro de IonList con una de las rutas.

import React from 'react';
import { IonApp, IonRouterOutlet, IonTabBar, IonTabButton, IonLabel, IonTabs, IonMenu, IonHeader, IonToolbar, IonTitle, IonContent, IonList, IonItem, IonMenuToggle } from '@ionic/react';
import { Route, Redirect } from 'react-router-dom';
import { IonReactRouter } from '@ionic/react-router';

import Cursos from './pages/Cursos';
import Objetivo from './pages/Objetivo';
import Objetivos from './pages/Objetivos';
import Filtrado from './pages/Filtrado';

.
.
.

const App: React.FC = () => (
    <IonApp>
        <IonReactRouter>
            <IonMenu contentId="main">
                <IonHeader>
                    <IonToolbar>
                        <IonTitle>
                            Objetivos
                        </IonTitle>
                    </IonToolbar>
                </IonHeader>
                <IonContent>
                    <IonList>
                        <IonMenuToggle>
                            <IonItem button routerLink="/filtrar">
                                <IonLabel>Filtrar</IonLabel>
                            </IonItem>
                        </IonMenuToggle>
                        <IonMenuToggle>
                            <IonItem button routerLink="/cursos">
                                <IonLabel>Cursos</IonLabel>
                            </IonItem>
                        </IonMenuToggle>
                        <IonMenuToggle>
                            <IonItem button routerLink="/objetivos">
                                <IonLabel>Objetivos</IonLabel>
                            </IonItem>
                        </IonMenuToggle>
                    </IonList>
                </IonContent>
            </IonMenu>
            <IonTabs>
                <IonRouterOutlet id="main">
                    <Route path="/cursos" exact>
                        <Cursos />
                    </Route>
                    <Route path="/objetivos" exact>
                        <Objetivos />
                    </Route>
                    <Route path="/filtrar" exact>
                        <Filtrado />
                    </Route>
                    <Route path="/curso/:id">
                        <Objetivo />
                    </Route>
                    <Redirect to="/cursos" />
                </IonRouterOutlet>
                <IonTabBar slot="bottom">
                    <IonTabButton tab="a" href="/objetivos">
                        <IonLabel>Objetivos</IonLabel>
                    </IonTabButton>
                    <IonTabButton tab="b" href="/cursos">
                        <IonLabel>Cursos</IonLabel>
                    </IonTabButton>
                </IonTabBar>
            </IonTabs>
        </IonReactRouter>
    </IonApp>
);

export default App;

Finalmente para poder invocar el uso del menú desplegable desde las otras páginas, debemos incorporar este botón como parte del IonToolbar.

Para Cursos.tsx y Objetivos.tsx.

<IonHeader>
    <IonToolbar>
        <IonButtons slot="start">
            <IonMenuButton />
        </IonButtons>
        <IonTitle>Cursos</IonTitle>
    </IonToolbar>
</IonHeader>

Ahora el menú desplegable con forma de botón de hamburguesa será visible.

VPN

  • Ir a la oferta de NordVPN

Moda

Accesorios