Angular自定义组件

作者: 菜园小饼zxy | 来源:发表于2021-02-18 19:45 被阅读0次

    前言

    最近做的Angular项目中有一个功能——数据库下载,在不同的组件中都有用到,所以期望将其抽象成一个公用组件,将代码得以复用。主要涉及到以下知识点:创建组件、组件的基本概念、组件与模块、引用组件、使用组件、组件交互等。

    创建组件

    在components文件夹下创建一个数据库下载的公用组件。

    打开命令行(使用vscode编辑器的小伙可以直接使用Ctrl+` 快捷键打开终端,然后一路跳转到components文件夹:

    cd src\app\components
    

    在此目录下执行指令:

    ng g c es-download
    

    上面指令的意思是创建一个名为es-download的组件,


    创建的组件.PNG

    使用上面的指令创建的组件是会被自动引用到components这个模块中的。
    components.module.ts

    import { EsDownloadComponent } from './es-download/es-download.component';  //引入组件
    @NgModule({
      declarations: [..., EsDownloadComponent],//声明组件
    })
    

    上面是在使用ng g c es-download指令时自动完成的,但若是想在其它的模块中使用这个es-download组件,还得将其导出,导出的方式是将这个组件添加至components.module.ts文件的exports中:

    @NgModule({
      declarations: [..., EsDownloadComponent],
      imports: [...],
      exports: [..., EsDownloadComponent],
    })
    export class ComponentsModule { }
    

    组件的基础概念

    查看es-download.component.ts

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'app-es-download',
      templateUrl: './es-download.component.html',
      styleUrls: ['./es-download.component.css']
    })
    export class EsDownloadComponent implements OnInit {
      constructor() { }
      ngOnInit(): void {
      }
    }
    

    可以看到此处从@angular/core中引入Component装饰器;并且建立了一个类,用@Component修饰它;在@Component中,设置了selector自定义标签和template模板。
    组件的几个关键知识点如下:

    组件的基础.PNG

    组件与模块

    模块是在组件之上的一层抽象,组件以及指令、管道、服务、路由等都能通过模块去组织。
    Angular提供了@NgModule装饰器来创建模块,一个应用可以有多个模块,有且只有一个根模块(Root Module),其他模块叫做特性模块(Feature Module)
    根模块是启动应用的入口模块,根模块必须通过bootstrap元数据来指定应用的根组件,然后通过bootstrapModule()方法来启动应用。
    建立一个根模块,命名为AppModule,并将它保存为app,module.ts
    app.module.ts中通过@NgModule的bootstrap元数据指定AppComponent组件

    import { NgModule } from '@angular/core';
    import { AppComponent } from './app.component';
    
    @NgModule({
      declarations: [...],
      imports: [...],
      providers: [...],
      bootstrap: [AppComponent]
    })
    export class AppModule { }
    

    AppComponent组件即为根组件。
    再创建一个main.ts,利用platformBrowserDynamic().bootstrapModule()方法来启动根模块,并将AppComponent组件的内容展示到页面上。

    import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
    import { AppModule } from './app/app.module';
    
    platformBrowserDynamic().bootstrapModule(AppModule)
      .catch(err => console.error(err));
    

    引用es-download组件

    由于我们最开始是将es-download组件引入到components这个模块中,并从这个模块中导出的,所以想要在其它模块中使用 es-download组件就得先引入components模块。
    将根模块AppModule,作为父组件来引用一下es-download组件
    首先在模块里引用:

    import { NgModule } from '@angular/core';
    import { ComponentsModule } from './components/components.module';
    
    @NgModule({
      declarations: [...],
      imports: [...,
        ComponentsModule,
        ],
    })
    export class AppModule { }
    
    

    引入了components模块就相当于是引入那个那个模块中的所有组件和方法。

    使用es-download组件

    根据selector: 'app-es-download',所以要使用es-download这个组件,需要在HTML中添加自定义标签
    <app-es-download></app-es-download>,然后Angular便会在此标签中插入EsDownloadComponent组件中指定的模板。

    import { Component, OnInit } from '@angular/core';
    
    @Component({
      selector: 'app-es-download',
      templateUrl: './es-download.component.html',
      styleUrls: ['./es-download.component.css']
    })
    

    组件交互

    事件交互

    由于es-download.component.html中的按钮有点击事件

    <button
      style="..."
      nz-button
      nzType="primary"
      (click)="esDownload()"
    >
      数据库下载
    </button>
    

    所以es-download.component.ts中需要实例化一个用来订阅和触发自定义事件的EventEmitter类

    import { Component, OnInit,Output,EventEmitter} from '@angular/core';//引入Output,EventEmitter
    
    @Component({
      selector: 'app-es-download',
      templateUrl: './es-download.component.html',
      styleUrls: ['./es-download.component.css']
    })
    export class EsDownloadComponent implements OnInit {
      @Output() click = new EventEmitter(); //通过输出属性@Output将数据流向父组件
    ......
    //点击事件函数
    esDownload() {
        .......
      }
    }
    

    数据交互

    父组件将数据通过属性绑定的方式流向子组件,子组件通过输入属性@Input获取来自父组件的数据。
    父组件的html文件:

    <app-es-download [name]="name" ></app-es-download>
    

    子组件的ts文件:

    import { Component, OnInit,Output,EventEmitter,Input} from '@angular/core';
    @Component({
      selector: 'app-es-download',
      templateUrl: './es-download.component.html',
      styleUrls: ['./es-download.component.css']
    })
    export class EsDownloadComponent implements OnInit {
      @Output() click = new EventEmitter();
      @Input() name:'';
    

    其中name数据是通过装饰器@Input来获取来自父组件的name对象,数据由父组件流出,在子组件中通过输入属性@Input完成数据的接收。

    相关文章

      网友评论

        本文标题:Angular自定义组件

        本文链接:https://www.haomeiwen.com/subject/vkagxltx.html