馃 Navegaci贸n dentro del proyecto

En este tutorial vamos a aprender acerca de la navegaci贸n.

馃嵖 驴Qu茅 es la navegaci贸n?

Existen diferentes tipos de patrones de navegaci贸n como:

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 sobreescribir 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 Aqui!</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.

Personalizar apariencia de los temas de Ionic Estudio de componentes de Ionic
comments powered by Disqus