Inhaltsverzeichnis
Komponentenkomponenten
Voraussetzungen
So erstellen Sie eine Komponente: Erstellen Sie eine Komponente mit Angular CLI ), hier Keine Einführung.
Lebenszyklusbedeutung
组件之间的通信(重要,必须掌握)
动态组件
Heim Web-Frontend js-Tutorial Werfen wir einen Blick auf die verwandten Konzepte der Angular10-Komponenten in einem Artikel

Werfen wir einen Blick auf die verwandten Konzepte der Angular10-Komponenten in einem Artikel

Jul 27, 2021 am 10:06 AM
组件

Dieser Artikel gibt Ihnen eine Einführung in die Komponenten in angular10 und stellt die Komponentenelemente, den Komponentenlebenszyklus, die Kommunikation zwischen Komponenten und die grundlegende Verwendung dynamischer Komponenten vor.

Werfen wir einen Blick auf die verwandten Konzepte der Angular10-Komponenten in einem Artikel

【Verwandte Tutorial-Empfehlung: „Angular Tutorial“】

Komponentenkomponenten

  • HTML-Vorlage
  • Typoskript, Verhalten definieren
  • CSS-Gruppe, kann mehrere CSS-Dateien einführen, sodass Sie mehrere definieren können CSS-Dateien in einer Komponente
//从angular主模块中引入Component(组件装饰器或组件注解)
import { Component } from '@angular/core';

//装饰器中以json的形式声明元数据
@Component({
  //它指定了一个叫 <app-root> 的元素。 该元素是 index.html 文件里的一个占位符
  //为什么这个组件跟入口index建立了联系呢?因为入口main.ts中绑定了主模块为appModule
  selector: 'app-root',   //在模板中找对应的标签,找到后创建并插入该组件实例
  templateUrl: './app.component.html',  // html模板
  styleUrls: ['./app.component.css'],   // css样式,可以引入多个css文件
  // 这个属性(内联模板)和templateUrl(外联模板)二选一,template后面可以直接跟html字符串
  // 注意在模板语法(反引号)中是使用插值表达式,不能使用${}插入值
  template: `<h1>{{title}}</h1>`   
})
//组件控制器,写逻辑代码的地方
export class AppComponent {
  title = 'myAngular';
  //构造函数可以用来进行属性的声明和初始化语句
  //在angular里面有个特别重要的点要记住:只能通过构造函数注入依赖
  constructor() {}
}
Nach dem Login kopieren

Voraussetzungen

  • Installieren Sie Angular CLI (npm install -g @angular/cli)
  • Erstellen Sie ein Angular-Projekt (ng new)

Wenn diese beiden Bedingungen nicht erfüllt sind, bitte Weitere Informationen finden Sie in der Build-Umgebung.

So erstellen Sie eine Komponente: Erstellen Sie eine Komponente mit Angular CLI ), hier Keine Einführung.

Komponentenlebenszyklus (High-Level-Inhalt, Master ngOnInit, ngOnDestroy, ngOnChanges, ngAfterViewInit())

Es gibt nur zwei Lebenszyklen, die häufig in der Arbeit verwendet werden (ngOninit und ngOnDestroy), und die anderen Lebenszyklen sind es Sehr selten verwendet; wenn Sie jedoch den Lebenszyklus von Komponenten beherrschen, werden Sie ein tieferes Verständnis für Winkel haben.

Lebenszyklusbedeutung

Der Lebenszyklus einer Komponenteninstanz beginnt, wenn Angular die Komponentenklasse instanziiert und die Komponentenansicht und ihre Unteransichten rendert. Der Lebenszyklus wird immer von einer Änderungserkennung begleitet, wobei Angular prüft, ob sich datengebundene Eigenschaften ändern, und Ansichts- und Komponenteninstanzen nach Bedarf aktualisiert. Der Lebenszyklus endet, wenn Angular die Komponenteninstanz zerstört und die von ihr gerenderte Vorlage aus dem DOM entfernt. Anweisungen haben einen ähnlichen Lebenszyklus wie Angular, der während der Ausführung Instanzen erstellt, aktualisiert und zerstört.

Anwendung: Ihre App kann Lebenszyklus-Hook-Methoden verwenden, um wichtige Ereignisse im Komponenten- oder Direktiven-Lebenszyklus auszulösen, um neue Instanzen zu initialisieren, bei Bedarf eine Änderungserkennung zu initiieren, auf Aktualisierungen während der Änderungserkennung zu reagieren und bei Bedarf Instanzen zu löschen .

So implementieren Sie Lebenszyklusereignisse

Jede Komponente oder Direktive kann einen oder mehrere Lebenszyklus-Hooks implementieren, die zum entsprechenden Zeitpunkt auf der Komponenten- oder Direktiveninstanz ausgeführt werden können.

Jede Schnittstelle verfügt über eine eindeutige Hook-Methode und ihre Namen bestehen aus dem Schnittstellennamen und dem Präfix ng. Die Hook-Methode der OnInit-Schnittstelle heißt beispielsweise ngOnInit(). Wenn Sie diese Methode in einer Komponenten- oder Direktivenklasse implementieren, ruft Angular sie auf, nachdem zunächst die Eingabeeigenschaften der Komponente oder Direktive überprüft wurden

ng generate component <project-name> // 创建一个组件

ng g c <project-name> // 缩写
Nach dem Login kopieren

Lebenszyklusübersicht

erfolgen se wenn Angular Legt eine datengebundene Eingabeeigenschaft fest oder setzt sie zurück. Diese Methode akzeptiert ein SimpleChanges-Objekt mit den aktuellen und vorherigen Eigenschaftswerten Dies kommt sehr häufig vor, sodass alles, was Sie hier tun, erhebliche Auswirkungen auf die Leistung hat. ngOnInit() Wird aufgerufen, nachdem die erste Runde von ngOnChanges() abgeschlossen ist, nur einmal aufgerufen. Initialisieren Sie die Direktive/Komponente, nachdem Angular zum ersten Mal die Datenbindung anzeigt und die Eingabeeigenschaften der Direktive/Komponente festlegt. Ein guter Ort für eine Komponente, um Anfangsdaten zu erhaltenEs ist wichtig, nur einmal aufzurufenngDoCheck() direkt nach ngOnChanges() jedes Mal, wenn eine Änderungserkennung durchgeführt wird, und ngOnInit(), wenn eine Änderungserkennung für durchgeführt wird Zum ersten Mal. Erkennen und reagieren Sie, wenn Änderungen auftreten, die Angular nicht selbst erkennen kann oder will. Es passiert so oft wie ngOnChangesngAfterContentInit()Der erste Aufruf von ngDoCheck(), nur einmal. Wird aufgerufen, nachdem Angular externen Inhalt in die Komponentenansicht oder die Ansicht projiziert, in der sich die Direktive befindet. Nur einmal aufgerufenngAfterContentChecked()ngAfterContentInit() und nach jedem ngDoCheck() Wird immer dann aufgerufen, wenn Angular den in die Komponente oder Direktive projizierten Inhalt überprüft hat. ngAfterViewInit()Der erste Aufruf von ngAfterContentChecked() erfolgt nur einmal. Wird nach der Initialisierung der Komponentenansicht und ihrer Unteransichten aufgerufen. Nur einmal aufrufenngAfterViewChecked()ngAfterViewInit() und jedes Mal nach ngAfterContentChecked(). Wird jedes Mal aufgerufen, nachdem die Änderungserkennung der Komponentenansicht und Unteransicht abgeschlossen ist. ngOnDestroy() Wird aufgerufen, bevor Angular die Direktive/Komponente zerstört. Wird aufgerufen und bereinigt, bevor jede Direktive/Komponente von Angular zerstört wird. Abonnieren Sie das Observable und trennen Sie den Event-Handler hier, um Speicherlecks zu verhindern. Es ist wichtig

重点生命周期详解

初始化组件和指令 ngOnInit

  • 在构造函数外部执行复杂的初始化。组件的构造应该既便宜又安全。比如,你不应该在组件构造函数中获取数据。当在测试中创建组件时或者决定显示它之前,你不应该担心新组件会尝试联系远程服务器。ngOnInit() 是组件获取初始数据的好地方
  • 在 Angular 设置好输入属性之后设置组件。构造函数应该只把初始局部变量设置为简单的值。请记住,只有在构造完成之后才会设置指令的数据绑定输入属性。如果要根据这些属性对指令进行初始化,请在运行 ngOnInit() 时设置它们

在实例销毁时进行清理 ngOnDestroy

这里是释放资源的地方,这些资源不会自动被垃圾回收。如果你不这样做,就存在内存泄漏的风险。

  • 取消订阅可观察对象和 DOM 事件。
  • 停止 interval 计时器。
  • 反注册该指令在全局或应用服务中注册过的所有回调。
  • ngOnDestroy() 方法也可以用来通知应用程序的其它部分,该组件即将消失

页面埋点

可以在组件中通过ngOnInit和ngOnDestroy方法统计页面的时长,

更好的做法可以通过指令实现ngOnInit和ngOnDestroy生命周期,用来统计页面时长

也可以通过路由守卫来记录页面出入栈所需要的时间

@Directive({selector: &#39;[appSpy]&#39;})
export class SpyDirective implements OnInit, OnDestroy {

  constructor(private logger: LoggerService) { }

  ngOnInit()    { this.logIt(`onInit`); }

  ngOnDestroy() { this.logIt(`onDestroy`); }

  private logIt(msg: string) {
    this.logger.log(`Spy #${nextId++} ${msg}`);
  }
}
Nach dem Login kopieren

使用变更检测钩子 ngOnchanges

一旦检测到该组件或指令的输入属性发生了变化,Angular 就会调用它的 ngOnChanges() 方法。

因为这个方法会频繁执行,所以要注意判断的计算量,会影响性能。

// 可以监听输入属性的变化
ngOnChanges(changes: SimpleChanges) {
  for (const propName in changes) {
    const chng = changes[propName];
    const cur  = JSON.stringify(chng.currentValue);
    const prev = JSON.stringify(chng.previousValue);
    this.changeLog.push(`${propName}: currentValue = ${cur}, previousValue = ${prev}`);
  }
}
Nach dem Login kopieren

组件之间的通信(重要,必须掌握)

一、父子组件的通信(基础)

父传子

1、父组件通过属性绑定向子组件传值

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-parent&#39;,
  template: `
    <app-child [msg]="msg"></app-child>
  `
})
export class ParentComponent {
  msg = &#39;父组件传的值&#39;;
}
Nach dem Login kopieren

2、子组件通过@Input接收数据

import { Component, Input } from &#39;@angular/core&#39;;

@Component({
  selector: &#39;app-child&#39;,
  template: `
    <p>{{msg}}</p>
  `
})
export class ChildComponent {
  @Input() msg: String;
}
Nach dem Login kopieren

子传父

1、子组件通过自定义事件,向父组件发送数据

import { Component, Input, EventEmitter, Output} from &#39;@angular/core&#39;;
,
@Component({
  selector: &#39;app-child&#39;,
  template: `
    <p>{{msg}}</p>
    <button (click)="vote()" >发送</button>
  `
})
export class ChildComponent {
  @Input() msg: String;
  @Output() voted = new EventEmitter<boolean>();
  
  vote() {
    this.voted.emit("子组件传的值");
  }
}
Nach dem Login kopieren

2、父组件通过监听自定义事件,接收子组件的传值

import { Component } from &#39;@angular/core&#39;;
@Component({
  selector: &#39;app-parent&#39;,
  template: `
    <app-child [msg]="msg" (voted)="voted($event)"></app-child>
  `
})
export class ParentComponent {
  msg = &#39;父组件传的值&#39;;
  voted(val){ //监听自定义事件的传值
      console.log(val)
  }
}
Nach dem Login kopieren

子组件怎么监听输入属性值的变化?(2种方法)

1、可以使用一个输入属性@Input()的 setter,以拦截父组件中值的变化。

import { Component, Input } from &#39;@angular/core&#39;;

@Component({
  selector: &#39;app-child&#39;,
  template: &#39;<h3>"{{name}}"</h3>&#39;
})
export class ChildComponent {
  @Input()
  get name(): string { return this._name; }
  set name(name: string) {
    this._name = (name && name.trim()) || &#39;<no name set>&#39;;
  }
  private _name = &#39;&#39;;
}
Nach dem Login kopieren

2、通过ngOnChange()来截听输入属性值的变化

当需要监视多个、交互式输入属性的时候,本方法比用属性的 setter 更合适。

import { Component, Input, OnChanges, SimpleChanges } from &#39;@angular/core&#39;;

@Component({
  selector: &#39;app-version-child&#39;,
  template: `
    <h3>Version {{major}}.{{minor}}</h3>
    <h4>Change log:</h4>
    <ul>
      <li *ngFor="let change of changeLog">{{change}}</li>
    </ul>
  `
})
export class VersionChildComponent implements OnChanges {
  @Input() major: number;
  @Input() minor: number;
  changeLog: string[] = [];

  ngOnChanges(changes: SimpleChanges) { //ngOnchange适合监听子组件多个输入属性的变化
    const log: string[] = [];
    for (const propName in changes) {
      const changedProp = changes[propName];
      const to = JSON.stringify(changedProp.currentValue);
      if (changedProp.isFirstChange()) {
        log.push(`Initial value of ${propName} set to ${to}`);
      } else {
        const from = JSON.stringify(changedProp.previousValue);
        log.push(`${propName} changed from ${from} to ${to}`);
      }
    }
    this.changeLog.push(log.join(&#39;, &#39;));
  }
}
Nach dem Login kopieren

父组件怎么读取子组件的属性和调用子组件的方法?(2种方法)

1、通过本地变量代表子组件

父组件不能使用数据绑定来读取子组件的属性或调用子组件的方法。但可以在父组件模板里,新建一个本地变量来代表子组件,然后利用这个变量来读取子组件的属性和调用子组件的方法,如下例所示。

思考:父组件可以通过这种方式读取子组件的私有属性和私有方法吗?

父组件

import { Component } from &#39;@angular/core&#39;;
import { CountdownTimerComponent } from &#39;./countdown-timer.component&#39;;

@Component({
  selector: &#39;app-countdown-parent-lv&#39;,
  template: `
  <h3>Countdown to Liftoff (via local variable)</h3>
  <button (click)="timer.start()">Start</button> //调用子组件方法
  <button (click)="timer.stop()">Stop</button>
  <div class="seconds">{{timer.seconds}}</div> //读取子组件属性
  <app-countdown-timer #timer></app-countdown-timer>
  `,
  styleUrls: [&#39;../assets/demo.css&#39;]
})
export class CountdownLocalVarParentComponent { }
Nach dem Login kopieren

子组件

import { Component, OnDestroy } from &#39;@angular/core&#39;;

@Component({
  selector: &#39;app-countdown-timer&#39;,
  template: &#39;<p>{{message}}</p>&#39;
})
export class CountdownTimerComponent implements OnDestroy {

  intervalId = 0;
  message = &#39;&#39;;
  seconds = 11;

  ngOnDestroy() { this.clearTimer(); }

  start() { this.countDown(); }
  stop()  {
    this.clearTimer();
    this.message = `Holding at T-${this.seconds} seconds`;
  }

  private clearTimer() { clearInterval(this.intervalId); }

  private countDown() {
    this.clearTimer();
    this.intervalId = window.setInterval(() => {
      this.seconds -= 1;
      if (this.seconds === 0) {
        this.message = &#39;Blast off!&#39;;
      } else {
        if (this.seconds < 0) { this.seconds = 10; } // reset
        this.message = `T-${this.seconds} seconds and counting`;
      }
    }, 1000);
  }
}
Nach dem Login kopieren

2、父组件调用@viewChild() (基础,推荐使用)

这个本地变量方法是个简单便利的方法。但是它也有局限性(只能在模板html中使用),因为父组件-子组件的连接必须全部在父组件的模板中进行。父组件本身的ts代码对子组件没有访问权。

当父组件类需要访问子组件时,可以把子组件作为 ViewChild,注入到父组件里面。

父组件类中访问子组件的属性和方法:

import { AfterViewInit, ViewChild } from &#39;@angular/core&#39;;
import { Component } from &#39;@angular/core&#39;;
import { CountdownTimerComponent } from &#39;./countdown-timer.component&#39;; //引入子组件

@Component({
  selector: &#39;app-countdown-parent-vc&#39;,
  template: `
  <h3>Countdown to Liftoff (via ViewChild)</h3>
  <button (click)="start()">Start</button>
  <button (click)="stop()">Stop</button>
  <div class="seconds">{{ seconds() }}</div>
  <app-countdown-timer></app-countdown-timer>
  `,
  styleUrls: [&#39;../assets/demo.css&#39;]
})
export class CountdownViewChildParentComponent implements AfterViewInit {

  //通过 @ViewChild 属性装饰器,将子组件 CountdownTimerComponent 注入到私有属性 timerComponent 里面。
  @ViewChild(CountdownTimerComponent) 
  private timerComponent: CountdownTimerComponent;

  seconds() { return 0; }

  // angular创建了组件的子视图后会调用它,注意获取子组件的属性,要在子组件视图加载之后
  ngAfterViewInit() {
    // 访问子组件属性
    setTimeout(() => this.seconds = () => this.timerComponent.seconds, 0);
  }

  start() { this.timerComponent.start(); } // 访问子组件的方法
  stop() { this.timerComponent.stop(); }
}
Nach dem Login kopieren

注意:(使用场景很多,必须掌握)

ngAfterViewInit() 生命周期钩子是非常重要的一步。被注入的计时器组件只有在 Angular 显示了父组件视图之后才能访问,所以它先把秒数显示为 0.

然后 Angular 会调用 ngAfterViewInit 生命周期钩子,但这时候再更新父组件视图的倒计时就已经太晚了。Angular 的单向数据流规则会阻止在同一个周期内更新父组件视图。应用在显示秒数之前会被迫再等一轮。

使用 setTimeout() 来等下一轮,然后改写 seconds() 方法,这样它接下来就会从注入的这个计时器组件里获取秒数的值。

二、组件通过服务来通信(发布订阅者模式,基础,必须掌握)

父组件和它的子组件共享同一个服务,利用该服务在组件家族内部实现双向通信。

不仅局限于父子组件,只要组件与组件共享同一个服务,就可以实现数据通信。

<!--parent.component.html-->
<p style="width: 1000px;margin: auto">
<p class="card" style="width: 500px;float: left">
 <p class="card-header"> 父组件</p>

 <p class="card-body">
  <h5 class="card-title">父组件</h5>
  <p class="form-group">
   <label for="serviceoutput">父组件服务输入:</label>
   <input type="text"
       class="form-control"
       id="serviceoutput"
       placeholder="服务输入"
       [(ngModel)]="serviceInput"
   >
  </p>

  <button class="btn btn-primary" (click)="clickService()">Service方式</button>
 </p>

</p>
<app-child></app-child>
</p>
Nach dem Login kopieren
<!--child.component.html-->
<p class="card" style="width: 500px;">
 <p class="card-header">子组件</p>

 <p class="card-body">
  <h5 class="card-title">子组件</h5>
  <p class="form-group">
   <label for="serviceoutput">子组件服务输入:</label>
   <input type="text"
       class="form-control"
       id="serviceoutput"
       placeholder="服务输入"
       [(ngModel)]="serviceInput"
   >
  </p>

  <button class="btn btn-primary" (click)="clickService()">Service方式</button>
 </p>
</p>
Nach dem Login kopieren
//服务重点
//meditor.service.ts

import {Injectable} from &#39;@angular/core&#39;;
import {Subject} from &#39;rxjs/Subject&#39;;
import {Observable} from &#39;rxjs/Observable&#39;;

@Injectable()
export class MeditorService {
 private subject = new Subject<MeditorMsg>();
 constructor() {}
 // 获取订阅者
 public getObservable(): Observable<MeditorMsg> {
  return this.subject.asObservable();
 }

 // 推送信息
 public push(msg: MeditorMsg) {
  this.subject.next(msg);
 }
}

// 中间者信息
export interface MeditorMsg {
 id: string;
 body: any;
}
Nach dem Login kopieren
subscription: Subscription = null; //初始化一个订阅对象

//子组件构造函数,用于监听数据推送
constructor(private meditor: MeditorService) {
  this.subscription = meditor.getObservable().subscribe(
   msg => {
    console.log(msg);
    if (msg.id === &#39;parent&#39;) {   //id为parent,获取父组件数据
     this.serviceInput = msg.body;
    }
   }
  );
 }
// 子组件将数据推送到中间着,给订阅者
clickService() {
  this.meditor.push({id: &#39;parent&#39;, body: this.serviceInput});
 }

//父组件构造函数,用于监听数据推送
constructor(private meditor: MeditorService) {
  this.subscription = meditor.getObservable().subscribe(
   msg => {
    console.log(msg);
    if (msg.id === &#39;child&#39;) {    //id为child,获取子组件数据
     this.serviceInput = msg.body;
    }
   }
  );
 }

// 父组件将数据推送到中间着,给订阅者
clickService() {
  this.meditor.push({id: &#39;parent&#39;, body: this.serviceInput});
 }
 
// 注意:订阅一个对象,就是在生命周期结束前,要取消订阅。
ngOnDestroy() {
    this.subscription.unsubscribe();
}
Nach dem Login kopieren

思考: 这种发布订阅者模式适合全局状态管理吗?

三、可以通过本地缓存来实现通信(Cookie,LocalStorage、SessionStorage)

<!-- catch_namae_type.ts -->
// 目的是好维护
// 项目当中用到的页面缓存,需要在这里进行声明;key-value保持一致
// 声明规则,不同类型的缓存使用前缀 session_/ local_ / cookie_
// 动态设置缓存不用在这里声明,但是需要在key后面加&#39;_noSetType_&#39;标识
export const CatchNameType = {
  session_userInfo: &#39;session_userInfo&#39;, // 用户信息
  session_toekn: &#39;session_token&#39;, // token
  local_loginInfo: &#39;local_loginInfo&#39;, // 本地缓存用户名密码
};

<!--catch.ts-->
import { Injectable } from &#39;@angular/core&#39;;
// 定义这个类,主要是看全局定义了哪些本地缓存
import { CatchNameType } from &#39;./catch_namae_type&#39;;

// -------------------------------------------------------缓存工具类(三类方法)
// Cookie           (方法有:set/get/remove)
// SStorage(sessionStorage)  (方法有:set/get/remove/clear)
// LStorage(localStorage)    (方法有:set/get/remove/clear)
@Injectable({
  providedIn: &#39;root&#39;,
})
export class Catch {
  // cookie
  public static Cookie = {
    /**
     * cookie 存贮
     * @param key  属性
     * @param value  值
     * @param String expire  过期时间,单位天
     */
    set(key: string, value: any, expire: any): void {
      if (Catch.is_set_catch_name_type(key)) {
        const d = new Date();
        d.setDate(d.getDate() + expire);
        document.cookie = `${key}=${value};expires=${d.toDateString()}`;
      }
    },
    get(key: string): string {
      const cookieStr = unescape(document.cookie);
      const arr = cookieStr.split(&#39;; &#39;);
      let cookieValue = &#39;&#39;;
      // tslint:disable-next-line: prefer-for-of
      for (let i = 0; i < arr.length; i++) {
        const temp = arr[i].split(&#39;=&#39;);
        if (temp[0] === key) {
          cookieValue = temp[1];
          break;
        }
      }
      return cookieValue;
    },
    remove(key: string): void {
      document.cookie = `${encodeURIComponent(key)}=;expires=${new Date()}`;
    },
  };

  // sessionStorage
  public static SStorage = {
    set(key: string, value: any): void {
      if (Catch.is_set_catch_name_type(key)) {
        sessionStorage.setItem(key, JSON.stringify(value));
      }
    },
    get(key: string): any {
      const jsonString =
        sessionStorage.getItem(key) === &#39;undefined&#39;
          ? undefined
          : sessionStorage.getItem(key);
      return jsonString ? JSON.parse(jsonString) : null;
    },

    remove(key: string): void {
      sessionStorage.removeItem(key);
    },
    clear(): void {
      sessionStorage.clear();
    },
  };

  // localStorage
  public static LStorage = {
    set(key: string, value: any): void {
      if (Catch.is_set_catch_name_type(key)) {
        localStorage.setItem(key, JSON.stringify(value));
      }
    },
    get(key: string): any {
      const jsonString =
        localStorage.getItem(key) === &#39;undefined&#39;
          ? undefined
          : localStorage.getItem(key);
      return jsonString ? JSON.parse(jsonString) : null;
    },
    remove(key: string): void {
      localStorage.removeItem(key);
    },
    clear(): void {
      localStorage.clear();
    },
  };

  // 设置缓存的时候是否在catch_name_type里面声明
  static is_set_catch_name_type(key: string): boolean {
    let allow = false;
    // 对动态设置缓存不进行检查
    if (key.indexOf(&#39;_noSetType_&#39;) !== -1) {
      allow = true;
      console.log(&#39;动态设置缓存&#39;, key);
      return allow;
    }
    // 对命名规则进行检查
    const nameRule =
      key.indexOf(&#39;session_&#39;) !== -1 ||
      key.indexOf(&#39;local_&#39;) !== -1 ||
      key.indexOf(&#39;cookie_&#39;) !== -1;
    if (!nameRule) {
      allow = false;
      console.log(&#39;命名规则错误&#39;, key);
      return allow;
    }
    // 静态设置的缓存需要配置类型
    Object.values(CatchNameType).forEach((item) => {
      if (item === key) {
        allow = true;
      }
    });
    if (!allow) {
      console.log(&#39;缓存操作失败,请检查配置缓存类型&#39;);
    }
    return allow;
  }
}
Nach dem Login kopieren

四、页面路由传参也可以实现单向通信

这部分内容,我会在路由章节整理。

组件通信总结

所以组件通信大概有如下几种:

1、父子组件通信(1、@Input() @output 2、本地变量#val 3、@viewChild())

2、通过服务

3、页面缓存

4、页面级组件传参(两个页面等同于两个组件)

动态组件

组件的模板不会永远是固定的。应用可能会需要在运行期间按需加载一些新的组件。 通过下面的例子可以了解动态组件的基本使用

1、创建组件,被引入的组件

@Component({
  template: `<span>hello world</span>`
})
export class DynamicComponent { }
Nach dem Login kopieren

2、创建容器组件,用于加载动态组件

@Component({
  selector: &#39;app-container&#39;,
  template: `
    <div #dynamicContainer></div>
    <button (click)="createComponent()">Create</button>
  `
})
export class AppContainerComponent {
  // 声明容器
  @ViewChild("dynamicContainer", { read: ViewContainerRef }) container: ViewContainerRef;
}
Nach dem Login kopieren

在AppContainerComponent组件中,通过@ViewChild装饰器来获取视图中的模板元素,如果没有指定第二个查询参数,则默认返回 组件实例或相应的DOM元素,但这个示例中,我们需要获取ViewContainerRef实例也就是视图容器。可以在视图容器中创建、插入、删除组件等。

3、动态创建组件

在创建组件之前,需要注入ComponentFactoryResolver服务对象,该服务是动态加载组件的核心,可以将一个组件实例呈现到另一个 组件视图上。

  • 使用ComponentFactoryResolve将已声明但未实例化的组件解析成为可以动态加载的component
//依赖组件类型获取对应的factory,从名字上可以看出该factory是用来初始化组件的
const componentFactory = this.ComponentFactoryResolver(DynamicComponent);
//调用视图容器的createComponent方法并将组件添加到容器上。该方法内部会调用factory的create方法来初始化组件。
const modalContainerRef = this.container.createComponent(componentFactory);
Nach dem Login kopieren

4、为组件属性赋值

通过如下的方式为组件属性进行赋值

modalContainerRef.instance.property = ***;
Nach dem Login kopieren

5、销毁组件

在使用组件后,记得要销毁组件。

modalContainerRef.destroy();
Nach dem Login kopieren

6、组件注册

为了能够动态创建组件需要将组件在模块的entryComponents中声明。因为在entryComponents中声明的组件Angular都会创建一个 ComponentFactory并将其存储在ComponentFactoryResolver中,这是动态加载必需的步骤。

更多编程相关知识,请访问:编程入门!!

Das obige ist der detaillierte Inhalt vonWerfen wir einen Blick auf die verwandten Konzepte der Angular10-Komponenten in einem Artikel. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
3 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

So installieren Sie die DirectPlay-Komponente der alten Windows 10-Version So installieren Sie die DirectPlay-Komponente der alten Windows 10-Version Dec 28, 2023 pm 03:43 PM

Viele Benutzer stoßen beim Spielen einiger Spiele unter Win10 immer auf Probleme, wie z. B. ein Einfrieren des Bildschirms und unscharfe Bildschirme. Zu diesem Zeitpunkt können wir das Problem lösen, indem wir die Directplay-Funktion aktivieren, und die Bedienungsmethode der Funktion ist ebenfalls sehr einfach. So installieren Sie DirectPlay, die alte Komponente von Win10 1. Geben Sie „Systemsteuerung“ in das Suchfeld ein und öffnen Sie es. 2. Wählen Sie große Symbole als Anzeigemethode. 3. Suchen Sie nach „Programme und Funktionen“. 4. Klicken Sie links, um oder zu aktivieren Win-Funktionen ausschalten 5. Wählen Sie hier die alte Version aus. Aktivieren Sie einfach das Kontrollkästchen

Grundlagen der VUE3-Entwicklung: Verwendung von Erweiterungen zum Erben von Komponenten Grundlagen der VUE3-Entwicklung: Verwendung von Erweiterungen zum Erben von Komponenten Jun 16, 2023 am 08:58 AM

Vue ist derzeit eines der beliebtesten Front-End-Frameworks, und VUE3 ist die neueste Version des Vue-Frameworks. Im Vergleich zu VUE2 bietet VUE3 eine höhere Leistung und ein besseres Entwicklungserlebnis und ist für viele Entwickler zur ersten Wahl geworden. In VUE3 ist die Verwendung von Erweiterungen zum Erben von Komponenten eine sehr praktische Entwicklungsmethode. In diesem Artikel wird erläutert, wie Erweiterungen zum Erben von Komponenten verwendet werden. Was heißt erweitert? In Vue ist Extends ein sehr praktisches Attribut, das für untergeordnete Komponenten verwendet werden kann, um von ihren Eltern zu erben.

Wie implementiert man eine Kalenderkomponente mit Vue? Wie implementiert man eine Kalenderkomponente mit Vue? Jun 25, 2023 pm 01:28 PM

Vue ist ein sehr beliebtes Front-End-Framework. Es bietet viele Tools und Funktionen wie Komponentisierung, Datenbindung, Ereignisbehandlung usw., die Entwicklern beim Erstellen effizienter, flexibler und einfach zu wartender Webanwendungen helfen können. In diesem Artikel werde ich vorstellen, wie man eine Kalenderkomponente mit Vue implementiert. 1. Anforderungsanalyse Zunächst müssen wir die Anforderungen dieser Kalenderkomponente analysieren. Ein einfacher Kalender sollte über die folgenden Funktionen verfügen: Anzeige der Kalenderseite des aktuellen Monats; Unterstützung des Wechsels zum vorherigen oder nächsten Monat; Unterstützung beim Klicken auf einen bestimmten Tag;

Winkelkomponenten und ihre Anzeigeeigenschaften: Nicht-Block-Standardwerte verstehen Winkelkomponenten und ihre Anzeigeeigenschaften: Nicht-Block-Standardwerte verstehen Mar 15, 2024 pm 04:51 PM

Das Standardanzeigeverhalten für Komponenten im Angular-Framework gilt nicht für Elemente auf Blockebene. Diese Designwahl fördert die Kapselung von Komponentenstilen und ermutigt Entwickler, bewusst zu definieren, wie jede Komponente angezeigt wird. Durch explizites Festlegen der CSS-Eigenschaft display kann die Anzeige von Angular-Komponenten vollständig gesteuert werden, um das gewünschte Layout und die gewünschte Reaktionsfähigkeit zu erreichen.

Lassen Sie uns darüber sprechen, wie Vue Komponenten über JSX dynamisch rendert Lassen Sie uns darüber sprechen, wie Vue Komponenten über JSX dynamisch rendert Dec 05, 2022 pm 06:52 PM

Wie rendert Vue Komponenten dynamisch über JSX? Der folgende Artikel stellt Ihnen vor, wie Vue Komponenten mithilfe von JSX effizient dynamisch rendern kann. Ich hoffe, er wird Ihnen hilfreich sein!

So öffnen Sie die Einstellungen der alten Version von Win10-Komponenten So öffnen Sie die Einstellungen der alten Version von Win10-Komponenten Dec 22, 2023 am 08:45 AM

Die alten Win10-Komponenten müssen vom Benutzer selbst aktiviert werden, da viele Komponenten standardmäßig geschlossen sind. Der Vorgang ist sehr einfach Versionskomponenten? Öffnen 1. Klicken Sie auf Start und dann auf „Win-System“. 2. Klicken Sie, um die Systemsteuerung aufzurufen. 3. Klicken Sie dann auf das Programm unten. 4. Klicken Sie auf „Win-Funktionen aktivieren oder deaktivieren“. 5. Hier können Sie auswählen, was Sie möchten öffnen

Vue-Komponentenpraxis: Entwicklung von Paging-Komponenten Vue-Komponentenpraxis: Entwicklung von Paging-Komponenten Nov 24, 2023 am 08:56 AM

Vue-Komponentenpraxis: Einführung in die Entwicklung von Paging-Komponenten In Webanwendungen ist die Paging-Funktion eine wesentliche Komponente. Eine gute Paginierungskomponente sollte einfach und klar in der Darstellung sein, reich an Funktionen und leicht zu integrieren und zu verwenden sein. In diesem Artikel stellen wir vor, wie Sie mit dem Vue.js-Framework eine hochgradig anpassbare Paging-Komponente entwickeln. Wir erklären anhand von Codebeispielen ausführlich, wie man mit Vue-Komponenten entwickelt. Technologie-Stack Vue.js2.xJavaScript (ES6) HTML5- und CSS3-Entwicklungsumgebung

VSCode-Plug-in-Freigabe: ein Plug-in für die Echtzeitvorschau von Vue/React-Komponenten VSCode-Plug-in-Freigabe: ein Plug-in für die Echtzeitvorschau von Vue/React-Komponenten Mar 17, 2022 pm 08:07 PM

Wie kann man bei der Entwicklung von Vue/React-Komponenten in VSCode eine Vorschau der Komponenten in Echtzeit anzeigen? Dieser Artikel stellt Ihnen ein Plug-in für die Echtzeitvorschau von Vue/React-Komponenten in VSCode vor. Ich hoffe, es wird Ihnen hilfreich sein!

See all articles
HookTimingZweckHinweis
ngOnChanges()Wird aufgerufen, wenn sich der Wert des gebundenen Eingabeattributs ändert, der erste Aufruf muss vor ngOnInit()


Abmelden von beobachtbaren Objekten,
Löschen von Timern,
Aufheben der Registrierung aller von diesem Befehl registrierten Rückrufe global oder in Anwendungsdiensten.