Hoe de waarde van url.path in een Joystick-component te nemen en deze om te zetten in een dynamische breadcrumb-gebruikersinterface.
Aan de slag
Voor deze tutorial gaan we het full-stack JavaScript-framework van CheatCode, Joystick, gebruiken. Joystick brengt een front-end UI-framework samen met een Node.js-back-end voor het bouwen van apps.
Om te beginnen willen we Joystick via NPM installeren. Zorg ervoor dat u Node.js 16+ gebruikt voordat u installeert om compatibiliteit te garanderen (lees deze tutorial eerst als u wilt leren hoe u Node.js installeert of meerdere versies op uw computer uitvoert):
Terminal
npm i -g @joystick.js/cli
Hiermee wordt Joystick wereldwijd op uw computer geïnstalleerd. Na de installatie gaan we een nieuw project maken:
Terminal
joystick create app
Na een paar seconden ziet u een bericht dat u bent uitgelogd op cd
in uw nieuwe project en voer joystick start
. uit :
Terminal
cd app && joystick start
Hierna zou je app moeten werken en zijn we klaar om aan de slag te gaan.
Geneste routes toevoegen
Om een breadcrumb-gebruikersinterface te demonstreren, hebben we een set geneste routes nodig waarmee we kunnen werken. Om het simpel te houden, laten we beginnen met het openen van de index.server.js
bestand in de root van het project dat we zojuist hebben gemaakt en voeg een paar routes toe:
Terminal
import node from "@joystick.js/node";
import api from "./api";
node.app({
api,
routes: {
"/": (req, res) => {
res.render("ui/pages/index/index.js", {
layout: "ui/layouts/app/index.js",
});
},
"/nested": (req, res) => {
res.render("ui/pages/index/index.js", {
layout: "ui/layouts/app/index.js",
});
},
"/nested/path": (req, res) => {
res.render("ui/pages/index/index.js", {
layout: "ui/layouts/app/index.js",
});
},
"/nested/path/to": (req, res) => {
res.render("ui/pages/index/index.js", {
layout: "ui/layouts/app/index.js",
});
},
"/nested/path/to/:thing": (req, res) => {
res.render("ui/pages/index/index.js", {
layout: "ui/layouts/app/index.js",
});
},
"*": (req, res) => {
res.render("ui/pages/error/index.js", {
layout: "ui/layouts/app/index.js",
props: {
statusCode: 404,
},
});
},
},
});
In de app die we zojuist hebben gemaakt, de index.server.js
bestand is het belangrijkste "startpunt" voor de server van onze applicatie. Binnen bellen we naar de node.app()
functie van de @joystick.js/node
pakket om onze server op te starten, de API door te geven die we willen dat deze wordt geladen en de routes die we beschikbaar willen hebben in onze app.
Waar we ons hier op willen concentreren, zijn de routes
, en in het bijzonder alle routes die we hebben toegevoegd, beginnend met /nested
. Hier maken we een pseudo-genesteld URL-patroon dat we kunnen gebruiken om onze code voor het genereren van broodkruimels te testen.
Voor elke /nested
route, doen we precies hetzelfde:render de index
paginacomponent (we hebben zojuist de inhoud van de /
gekopieerd en geplakt de terugbelfunctie van de route voor elke /nested
route). Het verschil tussen elk is het pad zelf. Merk op dat we voor elke route die we hebben toegevoegd een extra niveau dieper gaan:
/nested
/nested/path
/nested/path/to
/nested/path/to/:thing
Het einddoel is dat we met deze structuur nu een geneste set routes hebben die we gemakkelijk kunnen weergeven als broodkruimels.
Vervolgens willen we de /ui/pages/index/index.js
. wijzigen bestand dat we hier weergeven om onze breadcrumbs-gebruikersinterface uit te bouwen.
Een dynamische broodkruimelgenerator toevoegen
Toen we onze app maakten met joystick create app
eerder kregen we ook een voorbeeldpaginacomponent op /ui/pages/index/index.js
. Laten we dat nu eens openen en de bestaande inhoud vervangen door een skeletcomponent die we kunnen gebruiken om onze breadcrumb-gebruikersinterface te bouwen.
/ui/pages/index/index.js
import ui from '@joystick.js/ui';
const Index = ui.component({
render: () => {
return `
<div>
</div>
`;
},
});
export default Index;
Als dat op zijn plaats is, is het eerste dat we willen doen de daadwerkelijke creatie van onze broodkruimels aansluiten en ons vervolgens concentreren op het weergeven ervan op de pagina. Om dit te doen, gaan we vertrouwen op de methods
eigenschap van een joystickcomponent.
/ui/pages/index/index.js
import ui from '@joystick.js/ui';
const Index = ui.component({
methods: {
getBreadcrumbs: (component) => {
// We'll build our breadcrumbs array here...
},
},
render: () => {
return `
<div>
</div>
`;
},
});
export default Index;
In een Joystick-component bevat de eigenschap Methods een object met diverse methoden (een andere naam voor functies die in JavaScript voor een object zijn gedefinieerd) die verband houden met onze component. Wat we nu willen doen is een functie definiëren getBreadcrumbs()
die het zware werk zal doen om ons URL-pad om te zetten in een reeks objecten die elke broodkruimel beschrijven die we willen weergeven.
/ui/pages/index/index.js
import ui from '@joystick.js/ui';
const Index = ui.component({
methods: {
getBreadcrumbs: (component) => {
const pathParts = component?.url?.path?.split('/').filter((part) => part?.trim() !== '');
return pathParts?.map((part, partIndex) => {
const previousParts = pathParts.slice(0, partIndex);
return {
label: part,
href: previousParts?.length > 0 ? `/${previousParts?.join('/')}/${part}` : `/${part}`,
};
}) || [];
},
},
render: () => {
return `
<div>
</div>
`;
},
});
export default Index;
We hebben de hele code hier voor de duidelijkheid gedumpt, dus laten we er doorheen gaan. Ten eerste is ons doel om deze functie getBreadcrumbs
. te kunnen aanroepen en laat het ons een reeks objecten retourneren waarbij elk object een van onze broodkruimels beschrijft.
Om daar te komen, moeten we het huidige pad krijgen waar onze gebruiker naar kijkt. We hebben hiervoor twee opties in onze app, beide even gemakkelijk. Ten eerste kunnen we in een webbrowser altijd het huidige pad krijgen via de window.location.pathname
globale waarde (location.pathname
in het kort). Omdat we met een Joystick-app werken, gaan we hier de url.path
. gebruiken waarde (die identiek is aan location.pathname
) beschikbaar op onze componentinstantie.
U zult merken dat bij het definiëren van een methode op een Joystick-component, als er geen argumenten worden doorgegeven aan die functie wanneer we deze aanroepen, Joystick automatisch het laatst mogelijke argument toewijst aan de componentinstantie. Als we bijvoorbeeld methods.getBreadcrumbs('something')
. hebben gebeld , zou de functiehandtekening hierboven veranderen in getBreadcrumbs: (someValue, component) => { ... }
.
Binnenkant van onze functie, van de component
we verkrijgen bijvoorbeeld het huidige pad met component.url.path
als een koord. Om bij een array te komen, moeten we eerst ons pad in delen splitsen. Om dat te doen, moeten we de .split()
. gebruiken functie beschikbaar op alle strings in JavaScript. Naar .split()
, we kunnen een teken doorgeven dat we willen splitsen op . Omdat we te maken hebben met een pad als /nested/path/to/123
we willen splitsen op de /
schuine streep naar voren. Het eindresultaat is een array als deze:
['', 'nested', 'path', 'to', '123']
Dit brengt ons het meest van de weg, maar merk op dat er hier een lege string is. Dat komt omdat toen we een .split('/')
. deden , de eerste schuine streep is geteld, maar omdat er niets aan voorafgaat, krijgen we gewoon een lege waarde.
Om dit aan te pakken, merk op dat de volledige regel hier is:
const pathParts = component?.url?.path?.split('/').filter((part) => part?.trim() !== '');
Wat dit zegt is "neem de url.path
waarde als een string, splits het in een array met behulp van de /
schuine streep naar voren als scheidingsteken en filter vervolgens elk deel in de resulterende array uit als het bijsnijden van alle witruimte resulteert in een lege tekenreeks."
Het eindresultaat? We krijgen een schone array om mee te werken, zoals ['nested', 'path', 'to', '123']
in onze pathParts
variabel.
Met deze array hebben we wat we nodig hebben om onze broodkruimels uit te bouwen. Vervolgens moeten we deze array in kaart brengen. Voor elke iteratie willen we het werk doen dat nodig is om ons breadcrumb-object te bouwen. Elke breadcrumb heeft twee eigenschappen:label
wat de weergegeven naam is die gebruikers zullen zien in de broodkruimelketen en href
wat de URL is waarnaar de breadcrumb wordt gelinkt.
Voor de label
, ons werk is eenvoudig:we hergebruiken gewoon de naam van het pad part
we zijn momenteel aan het rondlopen. href
is wat lastiger. Hier moeten we ervoor zorgen dat elke volgende broodkruimel weet wat er voor kwam, dus als we erop klikken, verwijzen we naar de juiste URL.
Om dit te doen, hebben we net binnen onze kaart een nieuwe variabele toegevoegd previousParts
waarvoor onze pathParts
. nodig is array en roept de .slice()
. aan methode erop, zeggende "geef me alles van het eerste element in de array tot de index van het huidige deel." Met andere woorden, dit levert ons een nieuwe op array met alles wat vóór de huidige part
. kwam .
Beneden op het object dat we teruggeven van onze .map()
we gebruiken een ternaire operator om de waarde van href
. in te stellen afhankelijk van de lengte van de previousParts
reeks. Als de lengte 0
. is , we staan aan het begin van ons pad en er zijn dus geen eerdere delen om te renderen. Als dit het geval is, retourneren we gewoon de href
als /${part}
.
Als er zijn previousParts
, we gebruiken de .join()
methode op die array om de array weer om te zetten in een string, waarbij de resulterende string wordt samengevoegd met de naam van de huidige part
. Het eindresultaat? Voor elke iteratie krijgen we zoiets als dit:
{ label: 'nested', href: '/nested' }
{ label: 'path', href: '/nested/path' }
{ label: 'to', href: '/nested/path/to' }
{ label: '123', href: '/nested/path/to/123' }
Dat is het voor krijgen onze broodkruimels. Laten we ze nu op de pagina weergeven.
/ui/pages/index/index.js
import ui from '@joystick.js/ui';
const Index = ui.component({
methods: {
getBreadcrumbs: (component) => { ... },
},
css: `
.breadcrumbs {
display: flex;
}
.breadcrumbs li {
list-style: none;
}
.breadcrumbs li:before {
content: "/";
display: inline-flex;
margin-right: 10px;
}
.breadcrumbs li:not(:last-child) {
margin-right: 10px;
}
`,
render: ({ when, each, methods }) => {
const breadcrumbs = methods.getBreadcrumbs();
return `
<div>
${when(breadcrumbs?.length > 0, `
<ul class="breadcrumbs">
${each(breadcrumbs, (breadcrumb) => {
return `
<li><a href="${breadcrumb?.href}">${breadcrumb?.label}</a></li>
`;
})}
</ul>
`)}
</div>
`;
},
});
export default Index;
Het deel waar we aandacht aan willen besteden staat in de render()
functie. Hier hebben we de weergave van onze lege <div></div>
. verwisseld met onze broodkruimels.
Naar onze render()
functie, verwachten we dat Joystick ons een object zal doorgeven dat de huidige componentinstantie vertegenwoordigt. In plaats van render: (component) => {}
te schrijven hier gebruiken we JavaScript-destructuring om de specifieke variabelen die we van dat object willen, te "plukken". Dus, in plaats van component.when
. te schrijven , component.each
, enz., kunnen we gewoon when
. schrijven , each
, en methods
(verwijzend naar dezelfde eigenschappen met steno).
De methods
. gebruiken eigendom hiervan, net binnen render()
, bellen we naar methods.getBreadcrumbs()
het resultaat (onze reeks broodkruimelobjecten) opslaan in een variabele breadcrumbs
. Met deze array gebruiken we vervolgens de when()
renderfunctie in Joystick waarmee we wat HTML voorwaardelijk kunnen renderen wanneer de eerste waarde die we aan de functie doorgeven true
is .
Hier willen we een HTML-tekenreeks retourneren die een <ul></ul>
. weergeeft (die onze lijst met broodkruimels vertegenwoordigt). Binnen in die <ul></ul>
om elke broodkruimel weer te geven, gebruiken we de each()
render-functie om te zeggen, gegeven de array die als eerste argument is doorgegeven, roept u voor elk item in die array de functie aan die als tweede argument is doorgegeven.
Voor die functie verwachten we elk item te ontvangen in de array die we hebben doorgegeven aan each
, of, een van onze breadcrumb
voorwerpen. Binnen de functie verwacht Joystick dat we een reeks HTML retourneren voor elke iteratie van de breadcrumbs
reeks. Omdat we in een <ul></ul>
zitten tag, voor elke broodkruimel willen we een <li></li>
. weergeven tag met een <a></a>
label erin. Van daaruit gebruiken we gewone JavaScript-interpolatie om de waarde van onze href
door te geven en label
van de huidige breadcrumb
voorwerp.
Dat is het! Bovenaan hebben we een css
. toegevoegd eigendom met een aantal eenvoudige styling om dingen op te ruimen. Als we een browser openen en schakelen tussen onze geneste routes, zouden we onze breadcrumbs dynamisch moeten zien bijwerken.
Afsluiten
In deze zelfstudie hebben we geleerd hoe u enkele geneste routes in een Joystick-app kunt instellen. Vervolgens leerden we hoe we een Joystick-component konden maken die het huidige pad volgde en deze converteerde naar een reeks broodkruimelobjecten die we konden gebruiken voor weergave in onze gebruikersinterface. Ten slotte hebben we geleerd hoe we onze broodkruimels voorwaardelijk kunnen weergeven in onze gebruikersinterface, met behulp van Joystick's when
en each
renderfuncties.