组件
前端中的组件是一堆为了实现同一业务逻辑的代码文件的组合,将相关文件都放到同一个目录中,就形成了一个独立性非常强的组件。
Angular 中使用了Web Component 的标准来实现组件化。
组件是 Angular 应用的最小的逻辑单元,模块则是在组件之上的一层抽象。组件以及其他部分,如指令、管道、服务、路由等都可以被包含到一个模块中,外部通过引用这个模块来使用一系列封装好的功能。
可以把 Angular 应用想象成一棵树,模块是这棵树的树枝,组件是这棵树的叶子,每个 Angular 应用都必须要有一个根模块(树干),并且根模块中必须通过 Bootstrap 指定根组件,用于启动 Angular 应用。
创建组件
创建组件跟简单,可以通过一下三个步骤创建组件:
- 从
@angular/core中引入Component装饰器; - 建立一个普通的类,并用
@Component修饰它; - 在
@Component中,设置selector自定义标签和template/templateUrl模板以及styles/styleUrls样式。
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent { }
在新版的 Angular 中自定义标签需要以
app-开头,否则会报错。
以上代码会创建一个最简单的 Angular 组件,使用这个组件需要在 HTML 中添加 <app-root></app-root> 标签,然后 Angular 便会在此标签中插入组件中指定的模板。
组件的基础构成
组件由组件装饰器、组件元数据、模板和组件类组成。先来了解一下组件装饰器和组件类,后面有章节详细说明组件元数据和模板。
组件装饰器( Component Decorator )
每个组件类必须使用 @Component 进行修饰才能成为 Angular 组件; @Component 是 TypeScript 的语法,它是一个装饰器,任何一个 Angular 的组件都会用这个装饰器修饰,如果移除了这个装饰器,它将不再是 Angular 组件了。
组件类
组件实际上也是一个普通的类,组件的逻辑都在组件类里定义并实现。
组件元数据
在组件中的 @Component 装饰器部分,提供了额外的元数据以确定如何在运行时处理、实例化和使用组件:
- selector:用于定义组件标签名,也是此组件的元素选择器;
- template:定义组件宿主元素的模板;
- templateUrl:引用外联模板;
- styles:要应用于此组件视图的内联定义样式;
- styleUrls:要应用于此组件视图的外联样式表;
- animations:此组件的动画列表;
- providers:此组件及其子组件可用的
providers列表; - viewProviders:此组件及其视图子项可用的
providers列表; - exportAs:在模板中导出组件实例的名称;
- inputs:以数据绑定为组件输入类属性名称列表;
- moduleId:定义此组件的 ES/CommonJS 模块 ID;
- outputs:显示其他人可以订阅的输出事件的类属性名称列表;
- host:将类属性映射到元素绑定的事件和属性;
- encapsulation:此组件使用的样式封装策略;
- interpolation:在此组件模板中使用的自定义插值标记;
- queries:配置可以注入组件的查询;
- changeDetection: 更改此组件使用的检测策略.
每个组件只能指定一个模板,可以使用 template 或者 templateUrl 的引入方式。
styles 和 styleUrls 允许同时指定。如果同时指定,styles 中的样式会先被解析,然后才会解析 styleUrls 中的样式。
数据绑定
每个组件都会关联一个模板,这个模板最终会渲染到页面上,页面的这个 DOM 元素就是此组件实例的宿主元素;
组件是自描述的。可以与宿主元素交互,交互的形式包括:
- 显示数据
可以再模板中使用插值语法 {{}} 来显示组件中的数据。
- 双向数据绑定
在模板中通过形如 [(ngModel)]='property' 的方式进行双向数据绑定。
- 监听宿主元素事件以及调用组件方法
在模板中通过形如 (click)='fun()' 的方法响应 UI 事件并调用组件中的方法。
组件的生命周期
组件的生命周期由 Angular 内部管理,从组件的创建、渲染,到数据变动事件的触发,再到组件从 DOM 中移除, Angular 都提供了一系列的钩子。这些钩子可以让开发者很方便的在这些事件触发时,执行相应的回调函数。
组件提供了八个生命周期钩子,下面分别来看一下:
ngOnChanges
ngOnint 钩子用于响应组件输入值发生变化时触发的事件。该方法接受一个 SimpleChanges 对象,包含当前值和变化前的值。该方法在ngOnint 之前,或者当数据绑定输入属性的值发生变化时会触发。
ngOnChanges 当且仅当组件输入数据变化时被调用,这里的“输入数据”指的是通过 @Input 装饰器显式指定的那些变量。只要这个输入属性的值发生了改变.就会触发 ngOnChanges() 生命周期钩子.这个生命周期钩子被调用时会传入一个 SimpleChanges 对象,这个对象中包含了输入属性当前值和上一值。
@Input() name: string;
ngOnChanges(changes: SimpleChanges): void {
console.log(changes); // name:SimpleChange {previousValue: "a", currentValue: "ab", firstChange: false}
}
上面是定义了一个输入属性name并将从a它改为ab之后的打印结果,可能你还注意到了打印的结果中还有一个firstChange属性.它是一个Booleans,表明你是否是第一次改变。
同时,还有一点需要注意: 输入属性定义为引用类型和基本类型的时候其表现结果是不同的.当输入属性是基本类型时,每一次改变都会触发 ngOnChanges() 生命周期钩子,而当输入属性是引用类型时,改变引用类型 当中 的属性时,并不会触发 ngOnChanges() 生命周期钩子,只有将引用类型数据的指针指向另一块内存地址的时候才会触发 ngOnChanges() 生命周期钩子。
ngOnInit
ngOnint 钩子用于数据绑定输入属性之后初始化组件。该钩子方法会在第一次 ngOnChanges 之后被调用。
使用 ngOnInit 有以下两个重要的原因:
- 组件构造后不久就要进行复杂的初始化;
- 需要在输入属性设置完成之后才构建组件。
ngDoCheck
ngDoCheck 钩子用于变化监测,该方法会在每次变化监测发生时被调用,在 ngOnChanges() 和 ngOnInit() 之后。
ngDoCheck() 是 Angular 中的变更检测机制.它由 zone.js 来实现的。其行为是只要你的 Angular 中的某个组件发生异步事件,就会检查整个组件树,以保证组件属性的变化或页面的变化是同步的,所以 ngDoCheck() 的触发相当频繁的.并且是我们无法预料到的,也许我们在页面上的一个无意识操作,就会触发几个甚至几十个的 ngDoCheck() 生命周期钩子。每一个变化监测周期内,不管数据值是否发生了变化,ngDoCheck 都会被调用,因此这个方法要慎用。所以我们在使用ngDoCheck()生命周期钩子的时候一定要加上判断.以避免无用的触发干扰我们.
ngAfterContentInit
ngAfterContentInit 钩子在组件内引用外部组件时,外部内容嵌入到组件视图后调用,它在第一次 ngDoCheck 执行后调用,且只执行一次。
当父组件向子组件投影内容的时,在子组件内会初始化父组件的投影内容,此时会调用 ngAfterContentInit() 生命周期钩子.在整个组件生命周期中只会调用一次.如下所示:
<!--- 父组件 -->
<app-child>
<p>我是父组件向子组件的投影内容</>
</app-child>
<!--- 子组件 ChildComponent -->
<div>
//接受父组件的投影内容
<ng-content></ng-content>
</div>
ngAfterContentChecked
ngAfterContentChecked 钩子在组件内引用外部组件时,外部内容嵌入到组件视图后,或者每次变化监测的时候调用。ngAfterContentInit() 和每次 ngDoCheck() 之后调用。
当父组件向子组件的投影内容发生改变时会调用 ngAfterContentChecked() 生命周期钩子。它与 ngDoCheck() 类似,当投影内容发生改变时,就会执行变更检查机制,同时调用 ngAfterContentChecked() 生命周期钩子。此外,还有一点:当父组件和子组件都有投影内容时,会先执行父组件的生命周期钩子,它与下面要说的 ngAfterViewInit() 和 ngAfterViewChecked() 相反.
ngAfterViewInit
ngAfterViewInit 钩子会在 Angular 创建了组建的视图及其子视图之后被调用。在第一次 ngAfterContentChecked() 之后调用,只调用一次。
ngAfterViewChecked
ngAfterViewChecked 在 Angular 创建了组件的视图及其子组件视图之后被调用一次,并且在每次子组件变化监测时也会被调用。
当组件及其子组件的视图发生改变时,执行完变更检查机制后调用.当父组件和子组件都发生视图变化时,会先执行子组件的生命周期钩子.
注意: 这里所说的视图发生改变不一定是真正页面上的变化.只是Angular种所认为的视图变化.因为Angular本身并不能察觉到页面上显示的视图.所以在Angular认为,只要你在后台定义的属性发生了改变,就是视图有了变化.从而就会调用ngAfterViewChecked()生命周期钩子.
ngOnDestroy
ngOnDestroy 在销毁组件之前触发。那些不会垃圾自动回收的资源(比如已订阅的观察者事件、绑定过的 DOM 事件。通过 setTimeOut 或 setInterval 设置过得计时器等等)都应该在 ngOnDestroy 中手动销毁掉,从而避免发生内存泄漏等问题。
本文深入探讨Angular中的组件,包括组件的创建、组件元数据、模板和组件类。讲解了如何使用@Component装饰器创建组件,以及组件的生命周期钩子,如ngOnInit、ngOnChanges等。此外,还阐述了组件的数据绑定机制,如显示数据、双向数据绑定和监听事件。了解这些基础知识对于掌握Angular应用的构建至关重要。
175

被折叠的 条评论
为什么被折叠?



