最近在看Angular的官方文档,对比着vue中的一些概念,浅浅记录一下。
动态绑定属性
<img alt="photo" [src]="imageURL"> // 类似vue中的v-bind
@input
类似vue中的props,定义一个变量,用来接收父组件传进来的值
// user.component.ts
class UserComponent {
@Input() occupation = '';
}
// app.component.ts
@Component({
...
template: `<app-user occupation="Angular Developer"><app-user/>`
})
class UserComponent {}
@Output
类似于vue中的$emit,用来向父组件传递消息
// child.component.ts
@Component({...})
class ChildComponent {
@Output() addItemEvent = new EventEmitter<number>(); // 实例化EventEmitter
onClick() {
this.count++;
this.addItemEvent.emit(count); // 通过emit发射事件
}
}
// parent.component.ts
@Component({
selector: 'app-root',
...,
template: `
<app-child (addItemEvent)="addItem($event)" />
`,
})
@defer延迟加载
@Component({
selector: 'app-root',
template: `
<div>
@defer (on viewport) { // 表示下面这一整段会出现在视口时加载
<comments />
} @placeholder { // 没理解
<p>Future comments</p>
} @loading (minimum 2s) { // 表示被包裹的p标签只会展示两秒
<p>Loading comments...</p>
}
</div>
`,
NgOptimizedImage图片加载优化
// user.component.js
import { NgOptimizedImage } from '@angular/common'; // 引入
@Component({
standalone: true,
imports: [NgOptimizedImage], // 引入
template: `
...
<li>
Static Image:
<img ngSrc="/assets/logo.svg" alt="Angular logo" width="32" height="32" />
</li>
<li>
Dynamic Image:
<img [ngSrc]="logoUrl" [alt]="logoAlt" width="32" height="32" />
</li>`,
...
`,
})
注意: 使用ngSrc的图片要有明确的宽高,如果实在不能确定宽高,可以使用fill属性
priority可以让图片优先加载
<img ngSrc="www.example.com/image.png" height="600" width="800" priority />
ngModel 双向绑定
类似vue中的v-model,绑定表单的value值给某个变量
import {Component} from '@angular/core';
import {FormsModule} from '@angular/forms'; // ngModel指令在formsModule中,要先导入FormsMOdule
@Component({
selector: 'app-user',
template: `
<p>Username: {{ username }}</p>
<p>{{ username }}'s favorite framework: {{ favoriteFramework }}</p>
<label for="framework">Favorite Framework:
<input id="framework" type="text" [(ngModel)]="favoriteFramework" />
</label>
`,
standalone: true,
imports: [FormsModule], // 加入到import数组中
})
export class UserComponent {
username = 'youngTech';
favoriteFramework = ''; // input的值绑定到该变量
}
绑定表单
import {Component} from '@angular/core';
import {ReactiveFormsModule, FormControl, FormGroup} from '@angular/forms';
//
@Component({
selector: 'app-root',
template: `
<form [formGroup]="profileForm" (ngSubmit)="handleSubmit()">
<label>
Name
<input type="text" formControlName="name" />
</label>
<label>
Email
<input type="email" formControlName="email" />
</label>
<button type="submit">Submit</button>
</form>
<h2>Profile Form</h2>
<p>Name: {{ profileForm.value.name }}</p>
<p>Email: {{ profileForm.value.email }}</p>
`,
standalone: true,
imports: [ReactiveFormsModule],
})
export class AppComponent {
profileForm = new FormGroup({ // 创建表单对象给form元素绑定
name: new FormControl(''),
email: new FormControl(''),
})
handleSubmit():void { // ngSubmit事件的处理函数
alert(
this.profileForm.value.name + ' | ' + this.profileForm.value.email
);
}
}
表单校验
import {Component} from '@angular/core';
import {FormGroup, FormControl} from '@angular/forms';
import {ReactiveFormsModule,Validators} from '@angular/forms';
@Component({
selector: 'app-root',
template: `
<form [formGroup]="profileForm">
<input type="text" formControlName="name" name="name" />
<input type="email" formControlName="email" name="password" />
<button type="submit" [disabled]="!profileForm.valid">Submit</button> // 校验通过才可点击提交
</form>
`,
standalone: true,
imports: [ReactiveFormsModule],
})
export class AppComponent {
profileForm = new FormGroup({
name: new FormControl('',Validators.required), // 表示需要校验
email: new FormControl('',Validators.required),
});
}
@Injectable 服务注入
可以为整个应用提供数据服务
1.创建可注入的服务
// app/car.service.ts
import {Injectable} from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class CarService {
cars = ['Sunflower GT', 'Flexus Sport', 'Sprout Mach One'];
getCars(): string[] {
return this.cars;
}
getCar(id: number) {
return this.cars[id];
}
}
2.使用服务
// app/app.component.ts
import {Component, inject} from '@angular/core';
import {CarService} from './car.service';
@Component({
selector: 'app-root',
template: `
<p>Car Listing: {{ display }}</p>
`,
standalone: true,
})
export class AppComponent {
display = '';
carService = inject(CarService); // 使用inject将服务注入该变量
constructor() {
this.display = this.carService.getCars().join(' ⭐️ ');
}
}
基于构造函数的依赖注入
1.提供服务
// app/car.service.ts
import {Injectable} from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class CarService {
cars = ['Sunflower GT', 'Flexus Sport', 'Sprout Mach One'];
getCars(): string[] {
return this.cars;
}
getCar(id: number) {
return this.cars[id];
}
}
2.使用服务
import {Component} from '@angular/core';
import {CarService} from './car.service';
@Component({
selector: 'app-root',
template: `
<p>Car Listing: {{ display }}</p>
`,
standalone: true,
})
export class AppComponent {
display = '';
constructor(private carService: CarService) { // look herr
this.display = this.carService.getCars().join(' ⭐️ '); // now you can invoke the service's method
}
}
Popes管道
类似于vue中的计算属性和过滤器的结合,只能在模板中使用,且是纯函数
import {Component} from '@angular/core';
import {LowerCasePipe} from '@angular/common'; // 引入pipe
@Component({
selector: 'app-root',
template: `
{{ username | lowercase }} // 使用 结果是 roungtech
`,
standalone: true,
imports: [LowerCasePipe], // 放入imports
})
export class AppComponent {
username = 'yOunGTECh';
}
自定义管道
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
standaone: true,
name: 'star', // 管道名字
})
export class StarPipe implements PipeTransform {
transform(value: string): string { // transform函数写管道的逻辑
return `⭐️ ${value} ⭐️`;
}
}