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


    Route

    定义单个路由的配置对象,一组routes 数组中,单条route 对象的配置,将给定URL与每一个路由进行匹配

    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-masterpackages
    outersrcurl_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);
    
  • 相关阅读:
    ORACLE 表移动后必须做的事
    浅谈oracle的监听服务静态注册
    SAP HANA2.0 EXPRESS 下载安装及管理
    ORA14452: attempt to create, alter or drop
    【JAVA】Macbook eclipse快速抽取函数快捷键(extract method)
    Linux 报错误:The remote server returned an error 500
    网页可能暂时无法连接,或者它已永久性地移动到了新网址。
    kafka 原理和总结
    Timer 原理 到 spring 定时器任务
    centos 安装kafka
  • 原文地址:https://www.cnblogs.com/fangdongdemao/p/14275238.html
Copyright © 2020-2023  润新知