为什么这个问题在 Stack Overflow 上炸开了锅(也让你的大脑爆炸)?
\n你在编写你的第一个 Angular 项目。创建一个组件,给它加上 @Component 装饰器——一切正常。然后你在别人的代码中看到了 @Directive,心想:“为什么用这个?这不是一样的吗?”剧透:不,不一样。但 90% 的新手都会感到困惑。
“@Directive vs @Component in Angular”这个问题在 Stack Overflow 上获得了数千次浏览,这并非偶然。让我们一劳永逸地弄清楚它们的区别、何时使用什么,以及如何在面试中不丢脸。开始吧!
\n\n什么是 @Component?(剧透:它也是 @Directive)
\n首先——揭晓真相。@Component 是 @Directive 的一个子类型。是的,你没听错。Angular 中的任何组件都是一个指令。但有一个重要的区别:组件拥有模板(template)。
@Component 装饰器继承了 @Directive 的所有特性,并增加了它自己的“亮点”——渲染 HTML 的能力。如果说指令是“行为”,那么组件就是“行为 + 界面片段”。
一个简单的 TypeScript 组件示例
\nimport { Component } from '@angular/core';\n\n@Component({\n selector: 'app-hello',\n template: `<h1>你好,{{name}}!</h1>`,\n styles: ['h1 { color: blue; }']\n})\nexport class HelloComponent {\n name: string = '世界';\n}\n\n这里的 HelloComponent 是一个完整的组件。它有自己的模板、样式和逻辑。它可以在另一个模板中作为 <app-hello></app-hello> 使用。
什么是 @Directive?(纯粹的行为)
\n指令是一个带有 @Directive 装饰器的类,它修改现有 DOM 元素的行为或外观。指令没有自己的模板。它不创建新元素——它“附着”在已有元素上。
Angular 中有三种类型的指令:
\n- \n
- 组件(是的,它们也是指令)——带有模板。 \n
- 结构型指令——修改 DOM 结构(
*ngIf、*ngFor)。 \n - 属性型指令——改变元素的外观或行为(
ngClass、ngStyle)。 \n
一个 TypeScript 属性型指令示例
\nimport { Directive, ElementRef, HostListener } from '@angular/core';\n\n@Directive({\n selector: '[appHighlight]'\n})\nexport class HighlightDirective {\n constructor(private el: ElementRef) {}\n\n @HostListener('mouseenter') onMouseEnter() {\n this.el.nativeElement.style.backgroundColor = 'yellow';\n }\n\n @HostListener('mouseleave') onMouseLeave() {\n this.el.nativeElement.style.backgroundColor = null;\n }\n}\n\n这个指令在鼠标悬停时将元素高亮为黄色。它不创建新的 DOM 节点——它“修改”现有的节点。使用方式如下:<div appHighlight>悬停在我上面</div>。
@Directive 与 @Component 的关键区别
\n让我们来逐一梳理。下面这张表格将帮助你一劳永逸地记住它们的区别:
\n\n| 特性 | \n@Component | \n@Directive | \n
|---|---|---|
| 是否有模板(template) | \n✅ 是,必须的 | \n❌ 没有 | \n
| 是否创建新的 DOM 元素 | \n✅ 是(通过选择器) | \n❌ 否(应用于已有元素) | \n
| 是否有样式(styles) | \n✅ 是,可以隔离 | \n❌
博客书籍推荐推荐阅读 |