angular组件知识点总结

124 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

组件交互

  1. 通过输入型绑定把数据从父组件传到子组件
// hero-child.component.ts
@Input() hero!: Hero;
@Input('master') masterName = '';// 起别名,但是不推荐
// hero-parent.component.ts
<app-hero-child
  *ngFor="let hero of heroes"
  [hero]="hero"
  [master]="master">
</app-hero-child>
  1. 通过 setter 截听输入属性值的变化
  @Input()
  get name(): string { return this._name; }
  set name(name: string) {
    this._name = (name && name.trim()) || '<no name set>';
  }
  private _name=''
  1. 用ngOnChanges()监听属性值的变化
 ngOnChanges(changes: SimpleChanges) {
   for (const propName in changes) {
      const changedProp = changes[propName];
      const to = JSON.stringify(changedProp.currentValue);
      if (changedProp.isFirstChange()) {
        console.log(`Initial value of ${propName} set to ${to}`);
      } else {
        const from = JSON.stringify(changedProp.previousValue);
        console.log(`${propName} changed from ${from} to ${to}`);
      }
    }  
 }
  1. 父组件监听子组件的事件
// child
template: `
  <h4>{{name}}</h4>
  <button (click)="vote(true)"  [disabled]="didVote">Agree</button>
  <button (click)="vote(false)" [disabled]="didVote">Disagree</button>
`
export class VoterComponent {
  @Input()  name = '';
  @Output() voted = new EventEmitter<boolean>(); // boolean 为传递对象的类型
  didVote = false;

  vote(agreed: boolean) {
    this.voted.emit(agreed);
    this.didVote = true;
  }
}
// parent
template: `
  <h2>Should mankind colonize the Universe?</h2>
  <h3>Agree: {{agreed}}, Disagree: {{disagreed}}</h3>
  <app-voter
    *ngFor="let voter of voters"
    [name]="voter"
    (voted)="onVoted($event)"> // 以$event为传递的值
  </app-voter>
`
export class VoteTakerComponent {
  agreed = 0;
  disagreed = 0;
  voters = ['Narco', 'Celeritas', 'Bombasto'];

  onVoted(agreed: boolean) { // agreed 为攒底的对象
    if (agreed) {
      this.agreed++;
    } else {
      this.disagreed++;
    }
  }
}

5.父组件调用子组件方法

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>
`
// 2.
@ViewChild(CountdownTimerComponent) private timerComponent!: CountdownTimerComponent;
start() { this.timerComponent.start(); }
组件样式

拥有样式模块化功能,不会被模板嵌入的组件所继承,也不会被通过内容投影(如 ng-content)嵌进来的组件所继承。

特性:

  • 可以使用对每个组件最有意义的 CSS 类名和选择器。
  • 类名和选择器是局限于该组件的,它不会和应用中其它地方的类名和选择器冲突。
  • 组件的样式不会因为别的地方修改了样式而被意外改变。
  • 可以让每个组件的 CSS 代码和它的 TypeScript、HTML 代码放在一起,这将促成清爽整洁的项目结构。
  • 以后还可以修改或移除组件的 CSS 代码,而不用遍历整个应用来看它有没有在别处用到。

特殊的选择器

:host

被称为宿主元素,模板会渲染到其中。:host 伪类选择器可用于创建针对宿主元素自身的样式,而不是针对宿主内部的那些元素。

::host-context

以某些来自宿主的祖先元素为条件来决定是否要应用某些样式。

:host-context(.active) { // 当模板的父元素为 class 时触发。
  font-style: italic;
}

::ng-deep

任何带有 ::ng-deep 的样式都会变成全局样式。如果使用的话需要带上 :host 以防止污染其他组件。