routerLink
export type Params = {
[key: string]: any;
};
?name=333 问号传参
@Input() queryParams?: Params|null;
#sex
@Input() fragment?: string;
合并参数 保留参数
export type QueryParamsHandling = 'merge'|'preserve'|'';
@Input() queryParamsHandling?: QueryParamsHandling|null;
是否保留 #的参数
@Input() preserveFragment!: boolean;
是否推向历史记录
@Input() skipLocationChange!: boolean;
是否替换历史记录
@Input() replaceUrl!: boolean;
通过location.getState()查询
@Input() state?: {[k: string]: any};
相对路由
@Input() relativeTo?: ActivatedRoute|null;
相对路由
constructor(
private location:Location,
private route:ActivatedRoute
) {}
<a [routerLink]="['./d']" [relativeTo]="route">相对</a>
从list
路由的位置导航到child
路由路径
[{
path: 'parent',
component: ParentComponent,
children: [{
path: 'list',
component: ListComponent
},{
path: 'child',
component: ChildComponent
}]
}]
class ChildComponent {
constructor(private router: Router, private route: ActivatedRoute) {}
go() { // 相对
this.router.navigate(['../d'], {relativeTo: this.route})
}
}
绝对导航
参数
url string | UrlTree
定义路径的绝对路径。该函数不会将任何变化量应用于当前URL。
extras NavigationBehaviorOptions
interface NavigationBehaviorOptions {
/**
true,不会推入历史记录
*/
skipLocationChange?: boolean;
replaceUrl?: boolean;
state?: {[k: string]: any};
}
一个对象,其中包含修改导航策略的属性。
this.router.navigateByUrl("/team/33/user/11", { skipLocationChange: true })
页面使用
先添加出口
<router-outlet>
给定一个路由
[{ path: 'user/:name', component: UserCmp }]
<a routerLink="/user/bob">xxxx</a>
参数如果是
['/team', teamId, 'user', userName, {details: true}]
link 实际的路由为 `/team/11/user/bob;details=true`
或者这样写成这样的 ['/team/11/user', userName, {details: true}]
`/` 根路径, `./` 本级, `../` 上级
上案例
[{
path: '', component: TwoComponent, children: [
{
path: 'a', component: AComponent, children: [
{path: 'c', component: CComponent},
{path: 'd', component: DComponent},
{matcher:htmlFiles, component: FComponent}
]
},
{path: 'b', component: BComponent},
]
}]
我们从AComponent来实验
根路径都清楚就不说了
<a [routerLink]="['./c']">a/c</a>
<a [routerLink]="['../b']">b</a>
参数的编写,可以参考上面的参数
?debug=true 参数合并
<a [routerLink]="['/user/bob']" [queryParams]="{debug: true}" queryParamsHandling="merge"
[state]="{tracingId: 123}"
>
link to user component
</a>
导航参数
/results?page=1
this.router.navigate(['/results'], { queryParams: { page: 1 } });
/results#top
this.router.navigate(['/results'], { fragment: 'top' });
queryParamsHandling
`preserve` : 保留当前参数
`merge` : 合并当前参数
开始 /a/c?age=12 导航到 /a/d?age=12
this.router.navigate(['/a/d'], {queryParamsHandling: "preserve"})
// 加入参数也没有用,还是age=12,不会发现改变
this.router.navigate(['/a/d'], {queryParams:{age:1},queryParamsHandling: "preserve"})
开始 /view1?page=1 导航到 /view2?page=1&otherKey=2
合并参数
this.router.navigate(['/view2'],
{ queryParams: { otherKey: 2 },queryParamsHandling:"merge" });
preserveFragment 是否保留 #的参数
开始 /results#top 导航的位置 /view#top
this.router.navigate(['/view'], { preserveFragment: true });
为true则不会推向历史记录
this.router.navigate(['/view'], { skipLocationChange: true })
为true替换当前历史状态
this.router.navigate(['/view'], { replaceUrl: true });
使用的history.state
// c => d
go() {
this.router.navigate(['/a/d'], {state:{name:'sex'}})
}
// d
export class DComponent implements OnInit {
constructor(private location:Location) {
}
ngOnInit(): void {
// 2 查询到的参数
console.log(this.location.getState());
// `navigationId` 是导航的次数记录
// {name: "sex", navigationId: 4}
}
}
源码查询的方式
constructor(
private router: Router, private route: ActivatedRoute,
// 可以加上`tabindex=0` 来包含文本的元素可聚焦
@Attribute('tabindex') tabIndex: string, renderer: Renderer2, el: ElementRef) {
if (tabIndex == null) {
renderer.setAttribute(el.nativeElement, 'tabindex', '0');
}
}
可以判断如果不是数组就改成数字, !=null 就变成空数组
@Input()
set routerLink(commands: any[]|string|null|undefined) {
if (commands != null) {
this.commands = Array.isArray(commands) ? commands : [commands];
} else {
this.commands = [];
}
}
拿到默认的urlThree
get urlTree(): UrlTree {
return this.router.createUrlTree(this.commands, {
// 有 `relativeTo` 就改成相对路由可以使用 ./ ../ 否则就是用默认
relativeTo: this.relativeTo !== undefined ? this.relativeTo : this.route,
queryParams: this.queryParams,// 问号传参
fragment: this.fragment, // #
queryParamsHandling: this.queryParamsHandling,// 问好参数合并还是保留
preserveFragment: attrBoolValue(this.preserveFragment),//保留 # 参数
});
}
}
点击的时候跳转
@HostListener(
'click',
['$event.button', '$event.ctrlKey', '$event.shiftKey', '$event.altKey', '$event.metaKey'])
onClick(...):boolean {
...
const extras = {
skipLocationChange: attrBoolValue(this.skipLocationChange), 拖入历史记录
replaceUrl: attrBoolValue(this.replaceUrl), 替换历史
state: this.state //lotaion.getState() 拿值
};
this.router.navigateByUrl(this.urlTree, extras);
return false;
}
//我们看看navigateByUrl 传入的参数
navigateByUrl(url: string|UrlTree, extras: NavigationBehaviorOptions )
我们写一个简单的点击事件去实现看看
clickDown(): boolean {
let a:UrlTree = this.router.createUrlTree(['./d'], {
relativeTo: this.route
});
this.router.navigateByUrl(a)
return false
}
// 把树转成绝对路径的代码
this.router.serializeUrl(this.urlTree)// 加入urlTree 就是a