🚚 Lògica per al Router d’una SPA
La lògica darrere d’un encaminador conté els següents passos.
- Carregar la ruta. Identificar on ens trobem en el lloc. Es realitza a través d’una càrrega inicial de la ruta.
- Comparar la URL amb una de les nostres rutes. La URL a la qual ens volem moure, s’ha de comparar amb les rutes que tenim ja que la ruta sol·licitada ha d’estar entre les nostres rutes definides per poder ser carregada.
- Actualitzar la ruta a la barra de navegació. Per això podem utilitzar un mètode d’HTML conegut com
pushState
. Aquest mètode forma part de l’objecte window del nostre navegadorwindows.history.pushState
. Aquest mètode ens afegeix un estat a la nostra història de navegació i a l’afegir un estat nou es reflecteix en la barra de navegació. - Actualitzar DOM amb el nou amb tu. El nou contingut es pot enviar a través d’
innerHTML
.
🏗 Arquitectura de la nostra aplicació
L’arquitectura per a aquesta aplicació contempla un arxiu HTML on viurà el nostre template el qual rebrà el contingut que estarà canviant en el DOM.
D’altra banda la lògica de l’aplicació estarà en els nostres arxius .js
els quals seran tres com es mostra en el següent diagrama.
Estructura de carpetes amb les que treballarem. a
|- root|-- /js|--- index.js|--- router.js|--- routes.js|-- index.html|-- style.css
🧭 Per què SPA?
Les SPA com el seu nom indica són pàgines web d’una sola pàgina i la navegació dins d’ella passa sense la necessitat de recarregar el navegador.
💡 el propòsit de realitzar el routing amb JavaScript vainilla és entendre el funcionament de les llibreries de routing dels frameworks.
Per treballar amb l’URL farem ús de l’API history, la qual no és una característica pròpia de JavaScript sinó de navegador. Aquesta API porta un mètode anomenat pushState
que ens ajuda a portar les dades de l’stack de la navegació.
🖥 Anem a el codi
Comencem donant-li estructura al nostre template d’HTML. Recordem que la funcionalitat d’aquesta petita practica és fer un router amb JavaScript Vanilla pel que el nostre template serà el més senzill possible.
<!DOCTYPE html><html lang="es"><head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>SPA Routing</title> <link rel="stylesheet" href="style.css"></head><body> <!-- Botones de navegación --> <header> <button onclick="ROUTER.load('home')">Home </button> <button onclick="ROUTER.load('about')">About</button> <button onclick="ROUTER.load('contact')">Contact</button> </header> <!-- Aquí es donde se insertará el contenido según la página en la que nos encontremos --> <div></div> <!-- En estos archivos estará la mágica para la navegación --> <script src="./js/router.js"></script> <script src="./js/routes.js"></script> <script src="./js/index.js"></script></body></html>
Amb el nostre template HTML realitzat el següent pas serà definir el nostre diccionari de rutes, aquí estarà una llista de totes les rutes disponibles dins la nostra SPA i el contingut de cadascuna d’elles. a
const PATHS = { home: { path: "/", template: `<h1>🏠 Home</h1>`, }, about: { path: "/about", template: `<h1>👩🏻💻 Sobre mi</h1>`, }, contact: { path: "/contact", template: `<h1>📱 Contacto</h1>`, }}
l’arxiu següent a treballar serà el que conté tota la lògica per fer funcionar les nostres rutes, si ara treballarem en el router.js
. En el qual definirem una classe anomenada Router
, aquesta classe és la que inicializaremos al nostre index.js
, però això ho veurem més endavant.
class Router {
El primer serà definir un constructor per a la nostra classe. Les funcions d’aquest constructor serà carregar el nostre llistat de rutes i inicialitzar el router.
constructor(paths) { this.paths = paths; this.initRouter(); }
Amb el nostre constructor creat escriurem la lògica per iniciar el router. Aquesta funció s’encarrega d’identificar la ruta en què es troba el nostre navegador.
initRouter() { const { location: { pathname = "/" } } = window; const URL = pathname === "/" ? "home" : pathname.replace("/", ""); this.load(URL); }
Amb la ruta identificada, podem començar a treballar en la funció que s’encarregarà de carregar les pàgines que desitgi visualitzar l’usuari. Aquesta serà la funció load
que rep per defecte el paràmetre de home
ja que volem que aquest contingut sigui el contingut principal de la nostra SPA.
load(page = "home") { const { paths } = this; const { path, template } = paths || paths.error; const $CONTAINER = document.querySelector("#content"); $CONTAINER.innerHTML = template; window.history.pushState({}, "done", path); }}
Ara amb tota la lògica del nostre router construïda només ens resta inicialitzar la classe en el index.js
. a
const ROUTER = new Router(PATHS);
Ara per poder provar correctament la nostra petita SPA cal tenir un servidor local. Això es pot implementar de moltes maneres però jo recomano que si estan fent servir VSCode s’instal·lin al Live Server el qual els farà la vida més fàcil.
→ LiveServer
✅ Conclusions
Aquesta seria d’una forma molt bàsica la forma en què treballen els routers d’alguns frameworks de JavaScript com Angular o Vue. En el personal no recomano fer “a mà” el router llevat que sigui un projecte molt petitó. El millor és utilitzar les implementacions pròpies de cada framework.
Encara que clar, sempre és bo esbudellar una mica les coses i conèixer des de les bases.
El codi de l’article el poden trobar a el meu repositori de GitHub. Aquí els deixo l’enllaç.
→ Vanilla Router SPA