构建单页应用程序是一门艺术,有许多令人印象深刻的框架可供选择。angular 是用于构建 Web 和移动应用程序的最直观和广泛使用的框架之一。今天,Angular 10 已经发布,并且有许多令人印象深刻的功能。但是,在深入挖掘之前,您需要掌握组件。
首先要做的事情:设置依赖项
在冒险使用 Angular 之前,您需要确保已成功安装以下依赖项:
节点.js
角 CLI
您可以使用 NPM 全局安装 Angular CLI。
npm install -g @angular/cli
现在,您可以通过几种不同的方式启动 Angular 项目:
手动创建它,手动
使用 Angular CLI
从 GitHub 克隆并运行一个项目
以下是使用 Angular CLI 创建新项目的方法:
ng new my-project-name cd my-project-name
就是这样!现在你的 Angular 之旅已经开始了。在这篇文章中,我们将构建一个简单的计算器,用于使用 Angular 将两个数字相加。
什么是 Angular 组件?
在 Angular 中,我们使用指令。指令分为三种类型:结构、属性和组件。在接下来的几节中,我们将深入研究有关组件的所有内容。
Angular 中的组件是我们为呈现 UI 项目而设计和构建的元素。这些 UI 项将允许用户与应用程序交互并访问其功能。
在本教程结束时,您将能够在 Angular 中构建组件。更重要的是,您将了解沿途的每一步。
组件将从第一天开始在任何 Angular 项目中使用。在某种程度上,您可以将任何 Angular 项目视为许多连接组件的树。每个组件都将具有特定的功能和将呈现它的模板。一个模板可以在多个组件中重复使用。一组组件形成一个 Angular 应用程序,最终在浏览器中看到。
组件就像一个类,其中封装了元素的行为及其视图。行为包括加载或呈现的数据以及用户可以交互的方式,其视图是定义数据如何呈现的模板。
构建计算器组件
让我们通过创建一个用于添加两个数字的 Angular 组件来了解组件。我们不会在本教程中逐步创建组件,但您可以在我们的 GitHub 存储库中找到此应用程序的完整代码。
Component
使用装饰器 定义组件
装饰器Component
用于在 Angular 中定义一个组件。定义组件的元数据如下:
@Component({ selector: 'calculator', templateUrl: './calculator.component.html', styleUrls: ['./calculator.component.css'] }) export class Calculator{ }
在上面的定义中,selector
告诉应用程序需要使用该组件的应用程序 HTML 的哪些元素。templateUrl
告诉应用程序可以呈现什么。上述装饰器中的所有其他内容都是可选的。
什么是选择器?
selector
是 Angular 中的一个重要属性。它可以帮助应用程序确定放置组件的位置。选择器始终是一个字符串。选择器可以用三种不同的方式定义,每种方式都有一个独特的用例:
selector: 'calculator'
可以在将组件指定为<calculator>
HTML 中的元素时使用。selector: '.calculator'
如果组件将用作 CSS 元素,则可以使用它,这看起来像<div class="calculator">
在 HTML 中。selector: '[calculator]'
当组件应该用作属性时可以使用,看起来像<div calculator>
.
选择器可以简单也可以复杂,但黄金法则是让选择器尽可能简单。
什么是模板?
templateUrl
用于标识组件将使用的模板。模板的路径应该是相对的。对于与组件源代码位于同一文件夹中的模板,您可以使用templateUrl: './calculator.html'
或templateUrl: 'calculator.html'
。
不要使用服务器上 HTML 文件的绝对 URL。如果这样做,应用程序将无法编译。为什么?Angular 2+ 总是预编译代码并确保模板在构建过程中被内联。
您还可以选择templateUrl
使用该选项将选项替换为内联模板template
。这在简单组件中很有用,其中 typescript 代码和 HTML 不必位于不同的文件中。
这种方法对最终应用没有任何影响。为什么?无论采用哪种方法,都会生成一个捆绑包。
什么是styleUrl
?
组件从来都不是简单的;它总是加载多种样式。该styleUrl
属性的作用是帮助您包含特定于组件的 CSS。就像模板一样,您可以对styles
属性使用内联样式。但如果代码有大量样式,则需要将其分离到不同的文件中。
请注意,styleUrl
总是需要一个数组,因此您可以添加多个样式表。
样式封装
Angular 组件总是鼓励样式隔离和完全封装。这意味着子组件或父组件中的样式不会影响 UI 层次结构中的其他组件。
为了控制样式封装,Angular 提供了一个encapsulation
在Component
装饰器中调用的属性。封装可以具有以下值之一:
ViewEncapsulation.Emulated
是默认值。它创建了填充样式来模拟阴影根和 dom。ViewEncapsulation.ShadowDom
如果您的浏览器具有对 shadow DOM 的本机支持,则速度最快。ViewEncapsulation.None
,正如其名称所暗示的那样,使用全局样式并避免任何形式的封装。
在我们的计算器组件中使用该encapsulation
属性的语法如下:
import { Component, ViewEncapsulation } from '@angular/core'; @Component({ selector: 'calculator', templateUrl: './calculator.component.html', styleUrls: ['./calculator.component.css'], encapsulation: ViewEncapsulation.None }) export class Calculator{}
在上面的例子中,我们选择了ViewEncapsulation.None
. 这绝对是将通用样式应用于父组件和子组件的最佳方式。
Angular 组件和模块
在深入了解组件生命周期之前,让我们看看组件和模块是如何相互链接的。我们的计算器应用程序的模块如下:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { CalcComponent } from './calc/calc.component' @NgModule({ declarations: [ AppComponent, CalcComponent ], imports: [ BrowserModule ], providers: [], bootstrap: [AppComponent] }) export class AppModule { }
如果您创建一个组件,它必须作为模块的一部分包含在内。
如果不将新创建的组件添加到模块中,则会出现错误。
要将组件添加到模块中,您必须首先导入它。首先必须将导入的文件添加到declarations
数组中。现在,该组件将在整个应用程序中可见,并且可以被其他组件使用。
让我们看看@NgModule
指令中的每个数组代表什么:
declarations
确保指令和组件在模块范围内可用。Angular CLI 带有一个功能,指令和组件将自动添加到模块中。imports
用于导入和访问其他模块。这允许开发人员在应用程序中包含第三方模块。exports
如果您的项目创建一个库或多个模块,则使用。如果一个组件没有被导出,它就不能在其他地方使用。
组件生命周期
我们现在准备了解组件和指令的生命周期。请记住,每个组件都有一个生命周期,从创建到销毁。渲染组件的那一刻,组件及其子组件的生命周期就开始了。
了解生命周期事件在 Angular 应用程序中非常有用——它有助于开发人员正确观察和响应事件。
以下是 Angular 组件的生命周期钩子,按每个钩子的调用顺序排列。
组件构造函数
ngOnChanges
ngOnInit
ngDoCheck
ngAfterContentInit
ngAfterContentChecked
ngAfterViewInit
ngAfterViewChecked
ngOnDestroy
当一个组件被创建时,constructor
被调用。接下来按上述顺序调用各种钩子。某些钩子喜欢OnInit
并且AfterContentInit
只会被调用一次。同时,只要组件中的内容发生更改,就会调用其他钩子。最后,onDestroy
被调用一次。
上面的生命周期钩子有一个接口。要使用钩子,您应该实现接口。通常,界面带有功能,以ng
. 例如,如果要使用该ngOnInit
功能,则组件必须实现OnInit
接口。以下是 Angular 组件中生命周期钩子中常用接口和方法的快速总结。再一次,表格是根据实现时首先调用的方法进行排序的。
界面 | 方法 | 目的 |
OnChanges | ngOnChanges | 在构造函数之后调用,并且每当输入的值发生变化时调用。 |
OnInit | ngOnInit | 只调用一次。非常特定于组件或指令。这是从服务器加载数据的最佳位置。 |
DoCheck | ngDoCheck | 当 Angular 无法自动检查更改或绑定时,使用此方法。它会通知组件任何更改。 |
AfterContentInit | ngAfterContentInit | 只调用一次。它由组件初始化触发。 |
AfterContentChecked | ngAfterContentChecked | 每次更改组件内容时调用。 |
AfterViewInit | ngAfterViewInit | 一旦每个子组件都被初始化,这个生命周期钩子就会被调用。视图可能没有完全渲染,但内部视图已经由 Angular 准备好了。 |
AfterViewChanged | ngAfterViewChecked | 一旦每个子组件都经过验证和更新,就会调用这个钩子。 |
OnDestroy | ngOnDestroy | 如果组件准备好从 UI 中移除或销毁,则调用此钩子。这是一个保留监听器的好地方,这些监听器将取消订阅和取消注册可观察对象或计时器。 |
现在,如果您想在我们的计算器组件中添加一个生命周期挂钩,它将如下所示:
import { Component, OnInit } from '@angular/core'; @Component({ selector: 'calculator', templateUrl: './calculator.component.html', styleUrls: ['./calculator.component.css'], encapsulation: ViewEncapsulation.None }) export class Calculator implements OnInit { constructor() {} ngOnInit(): void { console.log('Component - On Init'); } }
创建计算器组件
我们正在构建的计算器应用程序的 UI 如下所示。
这是我们将添加到组件模板中的 HTML:
<div class="row"> <div class="col-12"> <input [(ngModel)]="number1" type="number" name="" placeholder="number"> </div> </div> <div class="row"> <div class="col-12"> <input [(ngModel)]="number2" type="number" name="" placeholder="number"> </div> </div> <button (click)="add()" class="button"> Add </button> <div class="result"> <span> Result : {{result}} </span> </div>
互动
渲染 UI 后,用户将对应用程序执行操作。现在,应用程序必须做出相应的响应。例如,当用户输入两个数字并单击Add时,我们的计算器必须添加。使用此功能连接输入框的最简单方法是通过ngModel
. 在 HTML 模板文件中,每个输入都可以链接到一个ngModel
变量。您可以在上面的 HTML 中看到,我们有许多ngModel
属性可以将 HTML 元素链接到我们的 TypeScript 代码。这些变量将在计算器组件源代码中声明和使用。
让我们看看这些ngModel
变量是如何在我们计算器的 TypeScript 代码中使用的。
//the component import { Component } from '@angular/core'; @Component({ selector: 'calc', templateUrl: 'calc.component.html', styleUrls: ['calc.component.css'] }) export class CalcComponent { public number1 : number; public number2 : number; public result : number; public add(){ this.result = this.number1 + this.number2 } }
每次用户在输入框中输入值,this.number1
都会this.number2
相应更新。为什么?ngModel
用于捕获输入。
当用户点击添加 按钮时,该add
函数被调用。如何?我们利用(click)
控件将按钮连接到add
方法。
当add
被调用时,this.result
基于this.number1
和进行更新this.number2
。一旦this.result
更新,UI 就会更新。如何?{{result}}
链接到this.result
。
这是一个包装!
我希望本教程有用。现在,您应该了解 Angular 组件的基础知识。您刚刚看到了如何定义组件、利用各种生命周期挂钩并最终参与用户交互。这仅仅是开始。Angular 组件还有很多其他功能。
- Component使用装饰器 定义组件
- 什么是选择器?
- 什么是模板?
- 什么是styleUrl?
- 样式封装
- Angular 组件和模块
- 组件生命周期
- 互动