前言

Angular的脚手架工具 @angular/cli有提供一个生成组件的命令:
ng generate component <component-name>
也可以手动新建。
下面介绍如何组织组件的结构。

定义组件

angular.js中使用类来定义组件,并且需要使用 @Component装饰器来装饰组件。以下就是组件的骨架结构。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: "hello-world"
  4. })
  5. export class HelloWorld {
  6. }

组件是一个独立的个体,包含独立的数据、模版和样式。那么分别如何定义?

定义模版

在组件使用 @Component装饰器的时候,传递的参数对象里面,有两个字段和模版相关联。分别是 templatetemplateUrl。顾名思义,templateUrl是一个模版文件,模版文件是一个 .html文件。
template
使用 template字段定义模版的话,值需要是一个html字符串,如下:

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: "hello-world",
  4. template: `
  5. <div>hello-world<div>
  6. `
  7. })
  8. export class HelloWorld {
  9. }

templateUrl
如果模版太复杂,写在 template字段里会很不方便。因此可以将模版单独抽离成一个文件,告诉组件模版文件的地址即可。

  1. <div>
  2. hello-world
  3. </div>
  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: "hello-world",
  4. templateUrl: "./helloworld.html"
  5. })
  6. export class HelloWorld {
  7. }

内部数据

模版中常常需要用到一些动态的数据,在组件中,直接将数据定义在类里面,作为类的属性即可。
模版里使用的时候用双花括号 {{ }}使用变量。
如果是在模板的 dom 属性里使用变量,则需要使用 []

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: "hello-world",
  4. template: `
  5. <div [id]="id">{{text}}<div>
  6. `
  7. })
  8. export class HelloWorld {
  9. text = "hello world";
  10. id = "id_test"
  11. }

内部方法

组件的方法直接定义在类里面作为类的属性。在模板中使用的时候,使用 ()来标记事件名。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: "hello-world",
  4. template: `
  5. <div>
  6. hello-world
  7. <button (click)="buttonClick()">点击</button>
  8. <div>
  9. `
  10. })
  11. export class HelloWorld {
  12. buttonClick() {
  13. console.log("点击了 button")
  14. }
  15. }

外部数据

在定义一个组件的时候,组件使用的数据除了自身定义的数据外,还会接收一些外部传递过来的数据。
外部数据使用 @Input()装饰器装饰。

  1. import { Component, Input } from '@angular/core';
  2. @Component({
  3. selector: "hello-world",
  4. template: `
  5. <div>
  6. hello-world
  7. <p>接收的数据 {{title}} </p>
  8. <div>
  9. `
  10. })
  11. export class HelloWorld {
  12. @Input() title!: string;
  13. }

使用组件的时候传递属性

  1. <hello-world title="hahah"></hello-world>

抛出事件(可用于改变外部数据)

当子组件想抛出一个事件的时候,需要暴露一个使用 @Output()装饰器装饰的 EventEmitter属性,属性名就是事件名。然后在适当的时机使用该属性的emit方法抛出数据。

  1. import { Component, Output, EventEmitter } from '@angular/core';
  2. @Component({
  3. selector: "hello-world",
  4. template: `
  5. <div>
  6. hello-world
  7. <button (click)="buttonClick()">点击</button>
  8. <div>
  9. `
  10. })
  11. export class HelloWorld {
  12. @Output() myClick = new EventEmitter<string>();
  13. buttonClick() {
  14. console.log("点击了 button");
  15. this.myClick.emit('click child button');
  16. }
  17. }

使用子组件的地方,通过 $event传递子组件 emit出来的数据。

  1. import { Component } from '@angular/core';
  2. @Component({
  3. selector: "app-root",
  4. template: `
  5. <main class="main">
  6. 我是 app
  7. <hello-world (myClick)="childClick($event)"></hello-world>
  8. </main>
  9. `
  10. })
  11. export class App {
  12. childClick(e: string) {
  13. console.log('app', e)
  14. }
  15. }