angular11源碼探索十八[路由RouterLink]

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路由的位置導航到childhtml

路由路徑
    [{
      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
相關文章
相關標籤/搜索