angular11源碼探索二十一[路由Route上]

Route

定義單個路由的配置對象,一組routes 數組中,單條route 對象的配置,將給定URL與每個路由進行匹配html

interface Route {
 // 配合的路徑,`**` 通配符能與任何URL匹配,`/*` 根路徑,也稱之爲絕對路徑  
  path?: string 
 // 路徑匹配策略, `prefix`或者`full` 默認`prefix`(前綴), `full` 完整匹配整個URL 
  pathMatch?: string
  // 自定義URL匹配功能  
  matcher?: UrlMatcher
    // 組件
  component?: Type<any>
    // 路徑匹配時重定向到的URL。若是URL以斜槓(/)開頭,則爲絕對值,不然相對於路徑URL。若是不存在,則路由器不會重定向。
  redirectTo?: string
    // 多個出口
  outlet?: string
    //用於查找CanActivate() 處理程序的依賴項注入令牌的數組,以肯定是否容許當前用戶激活組件。默認狀況下,任何用戶均可以激活
    // 前置守衛(進入) 後置守衛(進入子組件)
  canActivate?: any[]
  canActivateChild?: any[]
  // 中止守衛(離開)  
  canDeactivate?: any[]
  // 防止異步路由  
  canLoad?: any[]
  // 直接傳遞數據, resolve 延遲守衛的數據也放在這裏面  
  data?: Data
  //解決延遲守衛  
  resolve?: ResolveData
  children?: Routes
  // 延遲加載模塊  
  loadChildren?: LoadChildren
  // 路由防禦策略 
  runGuardsAndResolvers?: RunGuardsAndResolvers
}

UrlSegmentGroup

表示解析的當前URL段組。數組

是否有子節點
  hasChildren(): boolean {
    return this.numberOfChildren > 0;
  }
子節數
  get numberOfChildren(): number {
    return Object.keys(this.children).length;
  }
父節點
  parent: UrlSegmentGroup|null = null;
整個當前的路由節點數組
segments: UrlSegment[]
最後一個字帶了s, 是整個的路由節點
  toString(): string {
    return serializePaths(this);
  }
// 這組孩子的名單
public children: {[key: string]: UrlSegmentGroup})

UrlMatcher

export type UrlMatcher = (segments: UrlSegment[], group: UrlSegmentGroup, route: Route) =>
    UrlMatchResult|null;
segments 當前的路段集合
group   整個的路段結合
route  當前的配置路由的對象 //{matcher: ƒ, component: ƒ}
返回值
export type UrlMatchResult = {
  consumed: UrlSegment[];
  posParams?: {[name: string]: UrlSegment};
};

consumed 是消耗的URL段的數組。
posParams 是位置參數的地圖   這個還不懂

案例異步

export function htmlFiles(url: UrlSegment[]) {
  return url.length === 1 && url[0].path.endsWith('.html') ? ({consumed: url}) : null;
}

export const routes = [{ matcher: htmlFiles, component: AnyComponent }];

url_three 源碼解析

export class UrlTree {
  _queryParamMap!: ParamMap;
  constructor(
      /**總URL tree */
      public root: UrlSegmentGroup,
      /** 問好傳參*/
      public queryParams: Params,
      /** #描點 */
      public fragment: string|null) {}

  get queryParamMap(): ParamMap {
    if (!this._queryParamMap) {
      this._queryParamMap = convertToParamMap(this.queryParams);
    }
    return this._queryParamMap;
  }
  toString(): string {
    return DEFAULT_SERIALIZER.serialize(this);
  }
}

路徑
\angular-master\packages\router\src\url_tree.ts
咱們能夠經過測試文件提示裏面的用法
export class DefaultUrlSerializer implements UrlSerializer {
  /** 將url解析爲 `UrlTree` */
  parse(url: string): UrlTree {
    const p = new UrlParser(url);
    return new UrlTree(p.parseRootSegment(), p.parseQueryParams(), p.parseFragment());
  }

  /** 將「UrlTree」轉換爲url */
  serialize(tree: UrlTree): string {
    const segment = `/${serializeSegment(tree.root, true)}`;
    const query = serializeQueryParams(tree.queryParams);
    const fragment =
        typeof tree.fragment === `string` ? `#${encodeUriFragment(tree.fragment!)}` : '';

    return `${segment}${query}${fragment}`;
  }
}

測試用法測試

const url = new DefaultUrlSerializer();
  const tree = url.parse('one/two')
  url.serialize(tree)  // one/two
	
  const three=serializer.parse('/path/to?k=v&v=c')
  three.queryParams // {k: "v", v: "c"}

  const three=serializer.parse('/test?test=a&test=b&pages=5&pages=6')
    // 多個屬性不會出現替換現狀,而是把他變成數組
  three.queryParams // {pages: ["5", "6"],test: ["a", "b"] }

  const three = serializer.parse('/test#names')
  console.log(three.fragment);// names

  const three = serializer.parse('/test?name=xxx')
  console.log(three.queryParamMap.get('name'));// xxx

    const tree = serializer.parse('/one/two(left:three//right:four)');
    console.log(tree.root.children);
    //默認的出口 primary:segments:[UrlSegment:{parameters: {},path: "one"}, UrlSegment:{parameters: {},path: "two"}]
    //left的出口 left:segments:[UrlSegment:{parameters: {},path: "three"}]
    //right的出口 right:segments:[UrlSegment:{parameters: {},path: "four"}]

    const tree = serializer.parse('/(left:one)');
    console.log(tree.root.children['left'].segments);
    //left的出口 [UrlSegment:{parameters: {},path: "one"}]

   const tree = serializer.parse('/one/three/(two;sex=12//left:three;name=32)');
    console.log(tree.root.children['primary'].segments);
    //默認的出口 [UrlSegment:{parameters: {},path: "one"},UrlSegment:{parameters: {},path: "three"}]
    console.log(tree.root.children['primary'].children['primary']);
    //默認的出口 [UrlSegment:{parameters: {sex:12},path: "two"}]
    console.log(tree.root.children['primary'].children['left']);
    //默認的出口 [UrlSegment:{parameters: {name:32},path: "three"}]

 	  const u1 = `/one?foo=bar baz`;
      const u2 = `/one?foo=bar+baz`;
      const u3 = `/one?foo=bar%20baz`;

      const u1p = url.parse(u1);
	  u1p.queryParamMap.get('foo') // bar baz
	  後面兩個結果是同樣的
      const u2p = url.parse(u2);	
      const u3p = url.parse(u3);
相關文章
相關標籤/搜索