Angular - @Input装饰器通过getter和setter实现输入属性的场景
在 Angular 中,@Input
的 getter 和 setter 用于创建带有自定义逻辑的输入属性,它们允许你在属性值被读取或修改时执行特定操作。以下是详细说明:
核心作用
- 拦截输入值的变化:当父组件传递的数据发生变化时触发自定义逻辑
- 添加业务逻辑:在值被设置或读取时执行额外操作
- 数据验证/转换:对输入值进行格式化或验证
- 触发副作用:值变化时自动更新组件状态或触发其他方法
基本结构示例
import { Component, Input } from '@angular/core';
@Component({...})
export class ChildComponent {
private _data: any;
@Input()
get data(): any {
// 读取时的逻辑
return this._data;
}
set data(value: any) {
// 设置时的逻辑
this._data = this.processValue(value);
this.onDataChange();
}
private processValue(val: any): any {
// 数据转换/验证逻辑
return val;
}
private onDataChange(): void {
// 值变化后的操作
}
}
主要应用场景
1. 数据验证与转换
private _score: number = 0;
@Input()
get score(): number {
return this._score;
}
set score(val: number) {
// 确保分数在0-100之间
this._score = Math.min(100, Math.max(0, val));
}
2. 自动触发关联操作
private _darkMode: boolean = false;
@Input()
get darkMode(): boolean {
return this._darkMode;
}
set darkMode(val: boolean) {
this._darkMode = val;
this.updateTheme(); // 每次变化时更新主题
}
3. 计算派生数据
private _price: number = 0;
discountPrice: number = 0;
@Input()
get price(): number {
return this._price;
}
set price(val: number) {
this._price = val;
this.discountPrice = val * 0.9; // 自动计算折扣价
}
4. 调试/日志记录
set data(val: any) {
console.log('Input changed:', val);
this._data = val;
}
与普通 @Input 的对比
特性 | 普通 @Input | Getter/Setter @Input |
---|---|---|
逻辑执行时机 | 无 | 值变化时自动触发 |
数据转换能力 | 无 | 内置转换逻辑 |
关联操作触发 | 需手动监听 ngOnChanges | 自动在 setter 中触发 |
代码复杂度 | 简单 | 稍复杂但更灵活 |
最佳实践
- 私有属性备份:始终使用私有属性(如
_data
)存储实际值 - 避免重复触发:在 setter 中更新 UI 时注意防止无限循环
- 轻量级操作:Setter 中避免耗时操作,保持高性能
- 结合 ngOnChanges:复杂场景可与生命周期钩子配合使用
当需要简单的数据传递时,普通
@Input
更合适;当需要对输入值进行响应式处理时,getter/setter 是更强大的选择。
通过这种方式,Angular 组件可以更智能地响应输入数据的变化,实现声明式的数据流控制。