Üdvözöllek a modern webfejlesztés izgalmas világában! Ha valaha is készítettél már egyoldalas alkalmazást (SPA – Single Page Application) Vue.js-sel, akkor valószínűleg találkoztál azzal a kihívással, hogy hogyan kezeld a különböző „oldalak” vagy nézetek közötti navigációt anélkül, hogy a teljes alkalmazás újratöltődjön. Itt jön képbe a Vue Router, a Vue.js hivatalos útválasztó könyvtára, amely elegánsan és hatékonyan oldja meg ezt a problémát.
Ez az átfogó útmutató a Vue Router alapjaitól egészen a haladó funkciókig vezet el, legyen szó a navigációs őrökről, a lusta betöltésről vagy a dinamikus útvonalakról. Célunk, hogy a cikk végére magabiztosan tudd használni a Vue Routert bármilyen méretű Vue.js alkalmazásban.
Miért elengedhetetlen a Vue Router?
Az egyoldalas alkalmazások forradalmasították a webes felhasználói élményt azáltal, hogy zökkenőmentes és reszponzív felületeket biztosítanak, melyek a hagyományos többoldalas webhelyekhez képest sokkal gyorsabbnak érződnek. Az SPA-k lényege, hogy a böngésző csak egyszer tölti be a HTML, CSS és JavaScript fájlokat, majd a navigáció és az adatok frissítése JavaScript segítségével történik, anélkül, hogy a teljes oldal újratöltődne.
Azonban egy SPA-nak is szüksége van valamilyen módszerre, amellyel a felhasználó különböző nézetek között mozoghat, és a böngésző címsorában is tükröződik az aktuális állapot. Ezt a feladatot látja el a Vue Router. Lehetővé teszi, hogy deklaratív módon definiáljunk útvonalakat (route-okat), amelyek különböző Vue komponenseket jelenítenek meg, miközben fenntartja a böngésző előzményeit és támogatja a közvetlen hivatkozásokat (deep linking).
Kezdeti lépések: A Vue Router telepítése és beállítása
Mielőtt belemerülnénk a részletekbe, telepítenünk kell a Vue Routert a projektünkbe. Feltételezzük, hogy már van egy működő Vue.js projekted (pl. a Vue CLI segítségével létrehozva).
1. Telepítés
Nyisd meg a terminált a projektgyökérben, és futtasd az alábbi parancsot:
npm install vue-router@next
# vagy ha Yarn-t használsz
yarn add vue-router@next
A `@next` a Vue 3-hoz készült, a legújabb verziót jelöli. Ha Vue 2-t használsz, csak az `npm install vue-router` parancsot add ki.
2. A Router beállítása
A telepítés után létre kell hoznunk egy router példányt, és azt a Vue alkalmazásunkhoz kell adnunk. Hagyományosan ez egy külön fájlban történik (pl. src/router/index.js
).
Hozd létre a src/router/index.js
fájlt, és illessz be a következő tartalmat:
import { createRouter, createWebHistory } from 'vue-router';
import Home from '../views/Home.vue'; // Tegyük fel, hogy van egy Home.vue oldalad
import About from '../views/About.vue'; // És egy About.vue oldalad
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
component: About
}
];
const router = createRouter({
history: createWebHistory(), // Hash módot is választhatunk: createWebHashHistory()
routes
});
export default router;
Ezután illesztened kell a routert a Vue alkalmazásodba, általában a src/main.js
fájlban:
import { createApp } from 'vue';
import App from './App.vue';
import router from './router'; // Importáljuk a router példányt
createApp(App)
.use(router) // Használjuk a routert
.mount('#app');
Alapvető útválasztás: Navigáció és Komponens renderelés
Most, hogy a router be van állítva, nézzük meg, hogyan használhatjuk a különböző nézetek megjelenítésére és a navigációra.
1. Útvonalak definiálása
Az útvonalak a routes
tömbben vannak definiálva. Minden objektum egy útvonalat reprezentál, és legalább két tulajdonsággal rendelkezik:
path
: Az URL elérési útvonala (pl.'/'
,'/about'
).component
: A komponens, amelyet az útvonalra való navigáláskor meg kell jeleníteni.name
(opcionális, de ajánlott): Az útvonal egyedi neve, amit a programozott navigációhoz használhatunk.
2. Navigáció a <router-link>
segítségével
A felhasználók számára a leggyakoribb módja a navigációnak a <router-link>
komponens. Ez automatikusan egy szabványos <a>
tag-gé alakul a böngészőben, de a Vue Router kezeli a kattintási eseményt, hogy elkerülje az oldal újratöltését.
Példa a src/App.vue
fájlban:
<template>
<div id="app">
<nav>
<router-link to="/">Kezdőlap</router-link> |
<router-link to="/about">Rólunk</router-link>
</nav>
<router-view /> <!-- Itt fognak megjelenni a router komponensei -->
</div>
</template>
3. Komponens renderelése a <router-view>
segítségével
A <router-view>
komponens az a helytartó, ahol a router által kiválasztott komponens megjelenik. Bárhol elhelyezheted az alkalmazásodban, ahol szeretnéd, hogy a route komponensek renderelődjenek.
Dinamikus útválasztás: Paraméterek kezelése
Gyakran előfordul, hogy egy útvonalnak dinamikus adatokra van szüksége, például egy felhasználó profiljának vagy egy termék részleteinek megjelenítéséhez. Ezt a dinamikus útválasztás segítségével valósíthatjuk meg.
1. Útvonal paraméterek definiálása
Az útvonal paramétereket kettősponttal (:
) jelöljük az útvonalban:
const routes = [
// ...
{
path: '/users/:id', // :id a dinamikus paraméter
name: 'UserDetail',
component: UserDetail
}
];
2. Paraméterek elérése a komponensben
A komponensen belül a paramétereket a this.$route.params
objektumon keresztül érhetjük el:
<template>
<div>
<h1>Felhasználó adatai: {{ userId }}</h1>
</div>
</template>
<script>
export default {
computed: {
userId() {
return this.$route.params.id;
}
},
// Alternatívaként watch is használható, ha az id változhat
watch: {
'$route.params.id'(newId, oldId) {
console.log(`Az ID változott: ${oldId} -> ${newId}`);
// Frissítsd az adatokat az új ID alapján
}
}
}
</script>
3. Propok használata a paraméterek átadására (ajánlott)
A this.$route
direkt elérése a komponensekben szorosan összeköti a komponenst az útvonallal. Ennek elkerülésére a Vue Router lehetőséget biztosít a paraméterek propokként való átadására:
const routes = [
{
path: '/users/:id',
name: 'UserDetail',
component: UserDetail,
props: true // Ezzel a paraméterek propokként jutnak el a komponensbe
}
];
<template>
<div>
<h1>Felhasználó adatai: {{ id }}</h1>
</div>
</template>
<script>
export default {
props: ['id'], // Most az 'id' egy prop!
}
</script>
Beágyazott útvonalak (Nested Routes)
Egyes esetekben az elrendezésed több rétegű lehet, ahol egy fő komponensen belül is van navigáció. Erre szolgálnak a beágyazott útvonalak.
Tegyük fel, hogy a /user/:id
útvonalon belül szeretnénk megjeleníteni a felhasználó profilját, beállításait vagy posztjait.
const routes = [
{
path: '/users/:id',
component: User, // A User komponens tartalmazni fog egy <router-view>-t
children: [ // Itt definiáljuk a beágyazott útvonalakat
{
path: '', // Ez az alapértelmezett beágyazott útvonal a /users/:id -hoz
component: UserProfile
},
{
path: 'settings', // /users/:id/settings
component: UserSettings
},
{
path: 'posts', // /users/:id/posts
component: UserPosts
}
]
}
];
A User.vue
komponensnek tartalmaznia kell egy <router-view>
tag-et, hogy a gyermekkomponensek renderelődhessenek:
<template>
<div>
<h2>Felhasználó: {{ $route.params.id }}</h2>
<nav>
<router-link :to="{ path: `/users/${$route.params.id}` }">Profil</router-link> |
<router-link :to="{ path: `/users/${$route.params.id}/settings` }">Beállítások</router-link> |
<router-link :to="{ path: `/users/${$route.params.id}/posts` }">Posztok</router-link>
</nav>
<router-view /> <!-- Itt jelennek meg a UserProfile, UserSettings stb. -->
</div>
</template>
Programozott navigáció
Amellett, hogy a <router-link>
segítségével deklaratívan navigálunk, gyakran van szükségünk programozott navigációra, például egy űrlap elküldése után vagy egy gombnyomásra.
A router példányon (amely elérhető this.$router
néven a komponensekben) keresztül számos metódus áll rendelkezésünkre:
1. router.push(location)
Ez a metódus új bejegyzést ad a böngésző előzményeinek verembe, így a felhasználó a „Vissza” gombbal visszanavigálhat. A location
lehet:
- String path:
this.$router.push('/users/123')
- Object path:
this.$router.push({ path: '/users/123' })
- Named route:
this.$router.push({ name: 'UserDetail', params: { id: 123 } })
- Query params és hash:
this.$router.push({ path: '/search', query: { q: 'vue' }, hash: '#results' })
2. router.replace(location)
Ez hasonló a push
-hoz, de nem ad új bejegyzést a verembe, hanem felülírja az aktuálisat. Így a felhasználó nem tud visszanavigálni az előző oldalra a „Vissza” gombbal.
this.$router.replace('/login')
(pl. sikeres bejelentkezés után)
3. router.go(n)
, router.back()
, router.forward()
router.go(n)
: Navigál előre vagy hátra a böngésző előzményeibenn
lépéssel.n
lehet pozitív (előre) vagy negatív (hátra).router.back()
: Egyenértékű arouter.go(-1)
-gyel.router.forward()
: Egyenértékű arouter.go(1)
-gyel.
Navigációs őrök (Navigation Guards)
A navigációs őrök (Navigation Guards) rendkívül erőteljes funkciók, amelyek lehetővé teszik, hogy a navigációs folyamat különböző pontjain logikát futtassunk le. Ezek segítségével autentikációt, jogosultságellenőrzést, adatok betöltését vagy az oldal címének dinamikus beállítását végezhetjük el.
Három fő típusuk van:
1. Globális őrök
router.beforeEach((to, from, next) => { ... })
: Minden navigáció előtt lefut.router.afterEach((to, from) => { ... })
: Minden navigáció után lefut (nem hívja meg anext()
-et).
Példa globális autentikációs őrre:
router.beforeEach((to, from, next) => {
const isAuthenticated = checkIfUserIsAuthenticated(); // Saját logikád
if (to.meta.requiresAuth && !isAuthenticated) {
next('/login'); // Átirányítás bejelentkezésre, ha kell
} else {
next(); // Folytassa a navigációt
}
});
A next()
függvény meghívása elengedhetetlen a navigáció folytatásához. Lehet next()
(folytatás), next(false)
(megszakítás), next('/path')
(átirányítás) vagy next(error)
(hiba). Ha globális őrben nem hívod meg a next()
-et, a navigáció soha nem fejeződik be.
2. Útvonal-specifikus őrök
Ezeket közvetlenül az útvonal definíciójában adhatjuk meg:
beforeEnter(to, from, next)
: Csak akkor fut le, ha az adott útvonalra navigálunk. Nem fut le, ha gyermek útvonalra lépünk be az aktuális útvonalon belül.
const routes = [
{
path: '/admin',
component: AdminDashboard,
meta: { requiresAuth: true, isAdmin: true },
beforeEnter: (to, from, next) => {
if (!isUserAdmin()) { // Saját admin ellenőrzés
next('/');
} else {
next();
}
}
}
];
3. Komponens-specifikus őrök
Ezeket közvetlenül a komponensben definiálhatjuk, és a komponens életciklusához kötődnek:
beforeRouteEnter(to, from, next)
: Mielőtt a komponens létrejön (ezért nem férünk hozzá athis
-hez). Anext(vm => { ... })
segítségével férhetünk hozzá az újonnan létrehozott komponens példányhoz.beforeRouteUpdate(to, from, next)
: Akkor fut le, ha az aktuális útvonal változik, de a komponens újrahasznosításra kerül (pl./users/1
-ről/users/2
-re). Hozzáférünk athis
-hez.beforeRouteLeave(to, from, next)
: Mielőtt elhagyjuk az adott komponenst. Hasznos lehet mentetlen változások ellenőrzésére. Hozzáférünk athis
-hez.
<script>
export default {
data() {
return { hasUnsavedChanges: true };
},
beforeRouteLeave(to, from, next) {
if (this.hasUnsavedChanges) {
const answer = window.confirm('Vannak mentetlen változásaid. Biztosan elhagyod az oldalt?');
if (answer) {
next();
} else {
next(false); // Maradjon az oldalon
}
} else {
next();
}
}
}
</script>
Meta adatok az útvonalakon (Route Meta Fields)
A meta
tulajdonság lehetővé teszi, hogy tetszőleges, egyéni adatokat társítsunk az útvonalakhoz. Ez rendkívül hasznos például jogosultsági információk vagy az oldal címének tárolására.
const routes = [
{
path: '/admin',
component: AdminDashboard,
meta: { requiresAuth: true, roles: ['admin', 'editor'], pageTitle: 'Admin Irányítópult' }
},
{
path: '/profile',
component: UserProfile,
meta: { requiresAuth: true, pageTitle: 'Saját Profilom' }
}
];
Ezeket az adatokat aztán elérhetjük a navigációs őrökben vagy a komponensekben a to.meta
objektumon keresztül:
router.beforeEach((to, from, next) => {
if (to.meta.requiresAuth && !userIsLoggedIn()) {
next('/login');
} else {
document.title = to.meta.pageTitle || 'Alkalmazás Címe';
next();
}
});
Haladó technikák
1. Lusta betöltés (Lazy Loading / Code Splitting)
Nagyobb alkalmazások esetén a teljes JavaScript kód betöltése az elején lassíthatja az alkalmazás indítását. A lusta betöltés (Lazy Loading vagy Code Splitting) lehetővé teszi, hogy csak akkor töltsük be a komponens kódját, amikor az adott útvonalra navigálunk. Ez jelentősen javítja az alkalmazás teljesítményét.
const routes = [
{
path: '/',
name: 'Home',
component: () => import('../views/Home.vue') // Lusta betöltés
},
{
path: '/about',
name: 'About',
// Egyedi chunk névvel: webpackChunkName: "about"
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
];
A fenti szintaxis a JavaScript dinamikus import funkcióját használja, amit a modern build eszközök (pl. Webpack, Vite) automatikusan kód felosztásra (code splitting) fordítanak.
2. Átnevezett nézetek (Named Views)
Előfordulhat, hogy egyetlen útvonalon belül több, független <router-view>
-t szeretnénk használni, mindegyiket más-más komponenssel. Erre szolgálnak az átnevezett nézetek.
Először is nevezzük el a <router-view>
komponenseinket:
<template>
<div>
<h1>Fejléc</h1>
<router-view name="sidebar" /> <!-- Ez a sidebar -->
<router-view /> <!-- Ez a fő tartalom -->
<router-view name="footer" /> <!-- Ez a lábléc -->
</div>
</template>
Ezután az útvonal definícióban egy objektumot adunk a component
helyett, ahol a kulcsok a <router-view>
nevek:
const routes = [
{
path: '/dashboard',
components: { // 'component' helyett 'components'
default: DashboardMain, // Névtelen router-view
sidebar: DashboardSidebar, // 'sidebar' nevű router-view
footer: DashboardFooter // 'footer' nevű router-view
}
}
];
3. Scroll viselkedés kezelése (Scroll Behavior)
Egyoldalas alkalmazásokban, amikor navigálunk, az oldal pozíciója gyakran nem áll vissza a tetejére. Ezt a scrollBehavior
opcióval szabályozhatjuk a router példány létrehozásakor:
const router = createRouter({
history: createWebHistory(),
routes,
scrollBehavior(to, from, savedPosition) {
if (savedPosition) {
return savedPosition; // Visszaállítja az előző pozíciót, ha van
} else {
return { top: 0, left: 0 }; // Görgessen az oldal tetejére
}
}
});
Ez a funkció lehetővé teszi, hogy finomítsuk a felhasználói élményt, például visszaállítsuk a scroll pozíciót, ha a felhasználó visszanavigál, vagy görgessünk egy adott horgonyhoz (anchor) a lapon.
Tippek és bevált gyakorlatok
- Rendszerezés: Tartsd tisztán az útvonal definíciókat. Nagyobb alkalmazások esetén érdemes lehet az útvonalakat modulokba vagy funkcionális egységekbe bontani.
- 404 oldal: Mindig definiálj egy
path: '/:pathMatch(.*)*'
útvonalat, amely egy 404-es komponenst jelenít meg, ha semmilyen más útvonal nem illeszkedik. - Aliasok és átirányítások: Használd a
redirect
tulajdonságot egy útvonal átirányítására egy másikra, vagy azalias
-t, ha egy útvonalnak több elérési útvonala is van.{ path: '/home', redirect: '/' }, { path: '/about-us', alias: '/about', component: About }
- Navigációs őrök hierarchiája: Értsd meg, hogy az őrök milyen sorrendben futnak le (globális > útvonal-specifikus > komponens-specifikus).
Konklúzió
A Vue Router a modern Vue.js alkalmazások elengedhetetlen része. Legyen szó egyszerű oldalak közötti navigációról vagy összetett jogosultságkezelésről és lusta betöltésről, a Vue Router rugalmas és robusztus megoldást kínál.
Reméljük, hogy ez az útmutató segített megérteni a Vue Router alapjait és haladó funkcióit egyaránt. Ne habozz kísérletezni a különböző funkciókkal, és építsd be őket a következő Vue.js projektedbe. Boldog kódolást!
Leave a Reply