Angular路由配置data字段引用组件变量提示找不到toto如何解决
问题根因
- 语法错误:
Routes类型是数组,你当前用了对象符号{}包裹配置项,应该改为[]。 - 逻辑错误:路由配置属于应用初始化阶段就会解析的静态配置,执行时机远早于首个组件的实例化阶段,根本无法访问到组件内定义的运行时动态变量
toto,所以这个写法本身就不支持传递组件内的动态值,仅可用来传递编译前就确定的固定常量。
可行的路由传值方案
以下是Angular生态下所有支持动态传递组件变量到路由目标组件的实现方式:
1. 路径参数(参数暴露在URL路径中)
适合传递必填的短标识类参数,比如ID
路由配置
const routes: Routes = [ { path: 'two/:toto', component: TwoComponent } ]
首个组件跳转逻辑
代码跳转:
import { Router } from '@angular/router'; // 构造器注入router constructor(private router: Router) {} // 跳转时传入变量 goToTwo() { this.router.navigate(['/two', this.toto]); }
模板跳转:
<a [routerLink]="['/two', toto]">跳转到第二个组件</a>
第二个组件取值
import { ActivatedRoute } from '@angular/router'; constructor(private activatedRoute: ActivatedRoute) {} ngOnInit() { // 快照方式(参数不会变的场景用) const toto = this.activatedRoute.snapshot.params['toto']; // 订阅方式(同一路由参数会动态变化的场景用) this.activatedRoute.params.subscribe(params => { const toto = params['toto']; }) }
2. 查询参数(参数暴露在URL查询串中)
适合传递非必填的过滤类参数,比如页码、筛选条件
路由配置
不需要额外修改,保留原有配置即可:
const routes: Routes = [ { path: 'two', component: TwoComponent } ]
首个组件跳转逻辑
代码跳转:
goToTwo() { this.router.navigate(['/two'], { queryParams: { toto: this.toto } }); }
模板跳转:
<a [routerLink]="['/two']" [queryParams]="{toto: toto}">跳转到第二个组件</a>
第二个组件取值
ngOnInit() { // 快照方式 const toto = this.activatedRoute.snapshot.queryParams['toto']; // 订阅方式 this.activatedRoute.queryParams.subscribe(params => { const toto = params['toto']; }) }
3. 路由状态(参数不暴露在URL中,Angular 7+支持)
适合传递敏感、长度较长的参数,不会出现在地址栏,刷新页面参数依然保留
路由配置
不需要额外修改
首个组件跳转逻辑
代码跳转:
goToTwo() { this.router.navigate(['/two'], { state: { toto: this.toto } }); }
模板跳转:
<a [routerLink]="['/two']" [state]="{toto: toto}">跳转到第二个组件</a>
第二个组件取值
// 方式1:直接从浏览器history取 const toto = history.state.toto; // 方式2:从ActivatedRoute取 const toto = this.activatedRoute.snapshot.state['toto'];
4. 共享服务传值(无路由限制,全应用通用)
适合复杂传值场景,不管是不是通过路由跳转都可以用,支持跨多组件共享状态
第一步:创建共享服务
import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) export class DataShareService { // 用BehaviorSubject存值,支持订阅最新状态 private totoSubject = new BehaviorSubject<string>(''); public toto$ = this.totoSubject.asObservable(); setToto(value: string) { this.totoSubject.next(value); } }
首个组件传值
import { DataShareService } from './data-share.service'; constructor(private dataShareService: DataShareService) {} goToTwo() { // 跳转前先存值 this.dataShareService.setToto(this.toto); this.router.navigate(['/two']); }
第二个组件取值
constructor(private dataShareService: DataShareService) {} ngOnInit() { this.dataShareService.toto$.subscribe(toto => { // 拿到最新的toto值 console.log(toto); }) }
额外说明
如果你确实要用到静态路由的data配置,只能传递编译阶段就确定的固定常量,写法如下:
const routes: Routes = [ { path: 'two', component: TwoComponent, data: { toto: '固定的预设值,不能是组件内的动态变量' } } ]
取值方式为从activatedRoute.snapshot.data['toto']取即可。
内容的提问来源于stack exchange,提问作者Herge
相关产品推荐
相关产品推荐

