Angular Router для начинающих: понятный гайд с примерами

от автора

Представьте, что вы делаете сайт-визитку или интернет-магазин на Angular. У вас есть главная страница, страница «О нас» и страница с товарами. Логично, что при клике на ссылки пользователь должен переходить между этими страницами

В классических сайтах это решается просто: при каждом клике браузер запрашивает у сервера новую HTML-страницу. Но в современных SPA (Single Page Applications) всё работает иначе — приложение загружается один раз, а дальше мы просто подменяем содержимое внутри него

Именно за это отвечает Angular Router. Он позволяет:

  • описывать маршруты (какой URL → какой компонент);

  • переключаться между страницами без перезагрузки;

  • передавать параметры и query-параметры в адресной строке;

  • защищать маршруты с помощью Guard’ов;

  • подгружать части приложения по требованию (lazy loading).

Можно сказать, что Router — это сердце навигации в Angular-приложениях. Если вы его поймёте, то сможете строить полноценные многостраничные приложения, а не просто «выводить компонент на экран»

В этой статье мы разберём Angular Router пошагово: от простейшего примера с тремя страницами до более продвинутых вещей вроде Guard’ов и ленивой загрузки. Всё будет на живых примерах и максимально простым языком, чтобы вы смогли уверенно применить это в реальном проекте

Мини-проект: Pizza Router App 🍕

Чтобы разобраться с Angular Router, мы будем делать маленький сайт пиццерии. У него будут такие страницы:

  • /Главная (приветственный экран + популярные пиццы),

  • /menuМеню (список всех пицц),

  • /pizza/:idДетальная страница пиццы (динамический роут),

  • /contactsКонтакты.

По ходу статьи мы добавим:

  • queryParams (например, сортировка пицц по цене),

  • Guard (например, «только авторизованный пользователь может сделать заказ»),

  • Lazy loading (например, админка для добавления новых пицц).

1. Создаём страницы для пиццерии 🍕

Сначала сгенерируем компоненты:

ng g c components/home ng g c components/menu ng g c components/pizza ng g c components/contacts

Теперь у нас есть 4 компонента. Заполним их простым содержимым.

home.html

<h1>🍕 Добро пожаловать в Pizza Router App!</h1> <p>Здесь вы можете выбрать вкусную пиццу и заказать её онлайн</p> <a routerLink="/menu">Перейти в меню</a>

menu.ts

import { Component } from '@angular/core';  @Component({   selector: 'app-menu',   imports: [],   templateUrl: './menu.html',   styleUrl: './menu.scss' }) export class Menu {   pizzas = [     { id: 1, name: 'Маргарита', price: 450 },     { id: 2, name: 'Пепперони', price: 550 },     { id: 3, name: 'Четыре сыра', price: 600 },   ]; }

menu.html

<h2>Меню пицц</h2> <ul>   @for (pizza of pizzas; track pizza.id) {     <li>       <a [routerLink]="['/pizza', pizza.id]">         {{ pizza.name }} — {{ pizza.price }} ₽       </a>     </li>   } </ul>

pizza.ts

Здесь используем динамический параметр id

import {Component, inject, OnInit} from '@angular/core'; import {ActivatedRoute, RouterLink} from '@angular/router';  @Component({   selector: 'app-pizza',   imports: [     RouterLink   ],   templateUrl: './pizza.html',   styleUrl: './pizza.scss' }) export class Pizza implements OnInit {   private readonly route = inject(ActivatedRoute);   pizzaId: string | null = null;    ngOnInit() {     this.pizzaId = this.route.snapshot.paramMap.get('id');   } } 

pizza.html

<h2>Вы выбрали пиццу №{{ pizzaId }}</h2> <p>Здесь могла бы быть подробная информация о пицце (ингредиенты, фото, отзывы)</p> <a routerLink="/menu">⬅ Назад в меню</a> 

contacts.html

<h2>Контакты</h2> <p>📍 Адрес: ул. Angular, 42</p> <p>📞 Телефон: +7 (999) 123-45-67</p>

2. Настраиваем роутинг

Angular Router уже встроен, нужно лишь добавить наши роуты

// app.routes.ts  import {Routes} from '@angular/router'; import {Home} from './components/home/home'; import {Menu} from './components/menu/menu'; import {Pizza} from './components/pizza/pizza'; import {Contacts} from './components/contacts/contacts';  export const routes: Routes = [   {path: '', component: Home},   {path: 'menu', component: Menu},   {path: 'pizza/:id', component: Pizza},   {path: 'contacts', component: Contacts}, ]; 

Теперь в app.html добавим навигацию и место, где будут подставляться страницы:

<nav>   <a routerLink="/">Главная</a> |   <a routerLink="/menu">Меню</a> |   <a routerLink="/contacts">Контакты</a> </nav>  <!-- Сюда Angular будет рендерить выбранный компонент --> <router-outlet></router-outlet> 

Если сейчас запустить проект (ng serve), то можно уже кликать по ссылкам и переходить между компонентами 🎉

3. Дополнительные параметры маршрутов

У объекта маршрута можно указывать не только path и component. Вот самые важные:

redirectTo

Позволяет перенаправить пользователя на другой маршрут

{ path: '', redirectTo: 'menu', pathMatch: 'full' }

Теперь при заходе на / сразу откроется страница меню

pathMatch

Указывает, как сравнивать путь.

  • full — путь должен совпадать полностью

  • prefix — совпадение по началу

{ path: '', redirectTo: 'menu', pathMatch: 'full' }

Если бы мы поставили prefix, редирект срабатывал бы слишком часто (например, даже при /pizza/1)

title

Начиная с Angular 14, можно указывать заголовок страницы прямо в маршруте

{ path: 'menu', component: Menu, title: 'Меню пицц' }

Теперь при переходе на /menu в браузере будет Pizza Router App - Меню пицц

children

Для вложенных маршрутов. Например, сделаем «Личный кабинет»:

{   path: 'profile',   component: ProfileLayout,   children: [     { path: 'orders', component: Orders },     { path: 'settings', component: Settings },   ] }

canActivate

Для защиты маршрута. Например, доступ к профилю только авторизованным:

{ path: 'profile', component: ProfileLayout, canActivate: [AuthGuard] }

Ленивая загрузка (Lazy Loading) в Angular Router

По умолчанию Angular загружает весь код приложения при старте. Если проект маленький — это нормально. Но когда страниц становится десятки и сотни (например, интернет-магазин с личным кабинетом, админкой, корзиной, заказами) → bundle разрастается и первая загрузка приложения становится медленной

Как решает проблему Lazy Loading?

Мы можем «разбить» приложение на модули, и загружать их только тогда, когда пользователь реально заходит на этот раздел

Например, в нашем приложении «Пиццерия»:

  • обычным клиентам нужны только Главная, Меню, Контакты;

  • а вот админку (/admin) им загружать нет смысла

Базовый пример

Допустим, у нас есть такой роутинг

import {Routes} from '@angular/router'; import {Home} from './components/home/home'; import {Menu} from './components/menu/menu'; import {Pizza} from './components/pizza/pizza'; import {Contacts} from './components/contacts/contacts';  export const routes: Routes = [   {path: 'menu', component: Menu},   {path: 'pizza/:id', component: Pizza},   {path: 'contacts', component: Contacts},   { path: '', redirectTo: 'menu', pathMatch: 'full' } ]; 

Теперь добавим ленивый роут для админки:

export const routes: Routes = [   { path: 'menu', component: Menu },   { path: 'pizza/:id', component: Pizza },   { path: 'contacts', component: Contacts },   { path: '', redirectTo: 'menu', pathMatch: 'full' },    // 👇 ленивый роут со standalone компонентом   {     path: 'admin',     loadComponent: () =>       import('./pages/admin/admin').then(m => m.Admin),   }, ];

Поддержка вложенных маршрутов

Если админка сложнее и у неё есть вложенные страницы (/admin/orders, /admin/settings), то лучше вынести их в отдельный routes

export const routes: Routes = [   { path: 'menu', component: Menu },   { path: 'pizza/:id', component: Pizza },   { path: 'contacts', component: Contacts },   { path: '', redirectTo: 'menu', pathMatch: 'full' },    {     path: 'admin',     loadChildren: () =>       import('./pages/admin/admin.routes').then(m => m.adminRoutes),   }, ];

А внутри admin.routes.ts:

import { Routes } from '@angular/router'; import { AdminDashboard } from './dashboard/dashboard'; import { AdminOrders } from './orders/orders';  export const adminRoutes: Routes = [   { path: '', component: AdminDashboard },   { path: 'orders', component: AdminOrders }, ]; 

Когда использовать loadComponent, а когда loadChildren?

  • loadComponent — когда у тебя одна страница, типа /admin.

  • loadChildren — когда у тебя несколько маршрутов внутри раздела, например /admin/orders, /admin/settings

🎯 Заключение

Мы прошли большой путь:

  • разобрали базовые маршруты (path, component),

  • научились работать с параметрами (:id, queryParams),

  • посмотрели на дополнительные настройки (redirectTo, pathMatch, title),

  • сделали ленивая загрузку и вложенные роуты

Теперь вы знаете, как устроен Angular Router и можете уверенно использовать его в своих проектах

Хотите маленький сайт-визитку, интернет-магазин или целую админку — всё это реально построить на тех знаниях, что мы разобрали


ссылка на оригинал статьи https://habr.com/ru/articles/938804/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *