Angular组件如何通过接口传递属性 能否不使用@Input实现
Angular组件通过接口传属性及@Input替代方案说明
一、组件结合接口实现属性传递的方法
你只需要将组件的输入属性和接口做类型绑定即可,修改后的代码如下:
接口定义
export default interface Example { title: string; }
调整后的组件代码
import { Component, Input } from '@angular/core'; // 导入定义的接口 import Example from './example.interface'; @Component({ templateUrl: './Example.html', styleUrls: ['./Example.scss'], }) // 也可以让组件类直接实现接口,强制要求属性存在 export default class ExampleComponent implements Example { // 把原来的any类型替换为接口定义的类型,实现编译阶段的类型校验 @Input() title: string; }
这样写之后,TS会自动校验传入的title是否符合接口要求,传入非字符串类型的时候会直接抛出类型错误,避免运行时异常。
二、不使用@Input的实现方案
完全可以不用@Input传递属性,常用的替代方案有以下几种:
- 共享服务传值
定义一个可注入的共享服务,通过RxJS的Subject/BehaviorSubject托管数据,需要传值的地方调用服务的更新方法,组件内部订阅服务的数据流拿到属性值,适合父子组件、兄弟组件、跨层级组件全场景传值。
示例代码:// 共享服务定义 @Injectable({providedIn: 'root'}) export class ExampleService { private titleSub = new BehaviorSubject<string>(''); title$ = this.titleSub.asObservable(); setTitle(title: string) { this.titleSub.next(title); } } // 组件内使用 export default class ExampleComponent implements Example, OnInit { title: string; constructor(private exampleService: ExampleService) {} ngOnInit() { this.exampleService.title$.subscribe(title => this.title = title); } } - @ViewChild直接赋值
如果是父组件调用子组件的场景,可以在父组件通过@ViewChild获取子组件实例,直接给实例的属性赋值,不需要在子组件加@Input装饰器。
示例代码:// 父组件代码 @Component({ template: `<app-example #exampleRef></app-example>` }) export class ParentComponent implements AfterViewInit { @ViewChild('exampleRef') exampleComp: ExampleComponent; ngAfterViewInit() { this.exampleComp.title = '测试标题'; } } - 路由传值
如果组件是通过路由加载的,可以把属性放在路由的data配置或者query参数里,组件内注入ActivatedRoute读取对应的值即可。 - 全局状态管理
如果是大型项目用了NgRx、Akita等状态管理库,可以直接把属性存在全局状态里,组件内部选择对应状态拿到值,不需要通过Input逐层传递。
内容的提问来源于stack exchange,提问作者Kate
相关产品推荐
相关产品推荐

