Почему этот вопрос взрывает Stack Overflow (и ваш мозг)?
Вы пишете свой первый Angular проект. Создаете компонент, вешаете на него декоратор @Component — всё работает. Потом видите в чужом коде @Directive и думаете: «А зачем? Это же то же самое?». Спойлер: нет, не то же самое. Но путаница возникает у 90% новичков.
Вопрос «@Directive vs @Component in Angular» набрал тысячи просмотров на Stack Overflow не просто так. Давайте раз и навсегда разберемся, в чем разница, когда что использовать и как не опозориться на собеседовании. Поехали!
Что такое @Component? (Спойлер: это тоже @Directive)
Для начала — срыв покровов. @Component — это подтип @Directive. Да-да, вы не ослышались. Любой компонент в Angular — это директива. Но с одним важным отличием: у компонента есть шаблон (template).
Декоратор @Component наследует всё от @Directive и добавляет свою «фишку» — возможность отрисовывать HTML. Если директива — это «поведение», то компонент — это «поведение + кусок интерфейса».
Пример простого компонента на TypeScript
import { Component } from '@angular/core';
@Component({
selector: 'app-hello',
template: `<h1>Привет, {{name}}!</h1>`,
styles: ['h1 { color: blue; }']
})
export class HelloComponent {
name: string = 'Мир';
}
Здесь HelloComponent — это полноценный компонент. Он имеет свой шаблон, стили и логику. Он может быть использован в другом шаблоне как <app-hello></app-hello>.
Что такое @Directive? (Чистое поведение)
Директива — это класс с декоратором @Directive, который изменяет поведение или внешний вид существующего DOM-элемента. У директивы нет своего шаблона. Она не создает новый элемент — она «цепляется» к уже существующему.
В Angular есть три типа директив:
- Компоненты (да, они тоже директивы) — с шаблоном.
- Структурные директивы — изменяют структуру DOM (
*ngIf,*ngFor). - Атрибутные директивы — меняют внешний вид или поведение элемента (
ngClass,ngStyle).
Пример атрибутной директивы на TypeScript
import { Directive, ElementRef, HostListener } from '@angular/core';
@Directive({
selector: '[appHighlight]'
})
export class HighlightDirective {
constructor(private el: ElementRef) {}
@HostListener('mouseenter') onMouseEnter() {
this.el.nativeElement.style.backgroundColor = 'yellow';
}
@HostListener('mouseleave') onMouseLeave() {
this.el.nativeElement.style.backgroundColor = null;
}
}
Эта директива подсвечивает элемент желтым при наведении мыши. Она не создает новый DOM-узел — она «видоизменяет» существующий. Используется так: <div appHighlight>Наведи на меня</div>.
Ключевые отличия @Directive vs @Component
Давайте разложим по полочкам. Вот таблица, которая поможет вам запомнить разницу раз и навсегда:
| Характеристика | @Component | @Directive |
|---|---|---|
| Наличие шаблона (template) | ✅ Да, обязателен | ❌ Нет |
| Создает новый DOM-элемент | ✅ Да (через селектор) | ❌ Нет (применяется к существующему) |
| Наличие стилей (styles) | ✅ Да, можно изолировать | ❌ Нет (только через ElementRef) |
| ViewEncapsulation | ✅ Поддерживается | ❌ Не применимо |
| Используется как маршрут (Route) | ✅ Да | ❌ Нет |
| Основная задача | Создание переиспользуемых UI-блоков | Изменение поведения/внешнего вида |
Когда использовать @Directive, а когда @Component?
Это самый частый вопрос. Вот простое правило:
- Если вам нужно создать новый элемент интерфейса (кнопку, карточку, форму) — используйте
@Component. - Если вам нужно изменить поведение существующего элемента (подсветить, скрыть, добавить тултип) — используйте
@Directive. - Если вы сомневаетесь — спросите себя: «Этот код будет иметь свой собственный HTML?». Если да — компонент. Если нет — директива.
Жизненный пример из реального проекта
Представьте, что вы делаете админ-панель. Вам нужно:
- Компонент
UserCardComponent— отображает карточку пользователя с аватаркой, именем и кнопками. У него есть свой шаблон. - Директива
TooltipDirective— при наведении на карточку показывает всплывающую подсказку с email-ом пользователя. Директива «вешается» на компонентUserCardComponent.
Видите разницу? Компонент — это «что», директива — это «как».
Подводные камни для новичков
Вот три типичные ошибки, которые совершают начинающие Angular-разработчики:
Ошибка 1: Директива без селектора
Если вы забыли указать selector в @Directive, Angular не сможет найти вашу директиву. Для компонентов это тоже верно, но там селектор очевиден. Для директивы селектор — это атрибут в квадратных скобках: [myDirective].
Ошибка 2: Попытка вставить HTML в директиву
Вы не можете использовать
Блоги
Рекомендаций по книгам
Читайте также