12Angular路由

路由

Angular是单页程序,路由显示的路径不过是一种保存路由状态的机制,这个路径在web服务器中不存在

<router-outlet></route-outlet>

注意:

  1. 插入的视图位于router-outlet的下方,而非内部
  2. 页面中可以有多个具名的router-outlet(辅助插座),但匿名的只能有一个
  3. 使用得插座过多,反而会导致一些副作用,使路由难以理解。通常情况下,都可以使用子、孙路由的嵌套来解决。
npm i -g http-serve
ng build --prod//编译
http-server . //监听当前目录8080端口

此时强制刷新,找不到页面,返回404,通常需要重定向到index页

ng g c not-found --skipTests -c OnPush -s

创建路由模块

ng g m list --routing

路由定义

const routes:Routes = [
    {
        path:'',
        redirectTo:'home',
        pathMatch:'full'
    },
    {
        path:'home',
        component:HomeContainerComponent,
        children:[
            {
                path:'',
                redirectTo:'hot',
                pathMatch:'full',
            },
            {
                path:':tabLink',
                component:HomeDetailComponent
            } 
        ]
    },
    {
    //前面的都没有符合,通过通配符匹配到最后的404
        path:'**',
        component:NotFoundComponent
    }
]

需要动态传输路由表时,在path的值前面加一个“:”

导入RouterModule

根模块forRoot 子模块forChild

@NgModule({
    imports:[RouterModule.forRoot(routes,{enableTracing:true})],
    export:[RouterModule]
})

enableTracing可以跟踪url的变化,当导航发生变化时,会打印一堆日志。

为时刻监听路由的变化,

注意模块导入的顺序,AppRoutingModule是最后一个,否则会被其他的拦截。

路径参数

  • 配置

{path:':tabLink',component:HomeDetailComponent}

  • 激活,并设置激活样式

<a [routerLink]="['/home',tab.link]" routerLinkActive="active-link">...</a>

编程式导航this.router.navigate(['home',tab.link]);

  • 读取

this.route.paramsMap.subscribe(params => {...});

路由传参

this.router.navigateByUrl('/hero/' + id)
this.router.navigate(['/hero/', id])

const routes: Routes = [
    {
        path:'hero/:id',
        component:HeroDetailComponent
    }
]

子模块读取

export class HeroDetailComponent implements OnInit {
    hero$: Observalbe<Hero>
    constructor(private route: ActivatedRoute){} 
    ngOnInit(){
        this.hero$ = this.route.paramMap.pipe(
            switchMap(params =>{
            return this.service.getHero(params.get('id'))
        }))
    }
}
路径对象参数
  • 激活

<a [routerLink] = "['/home',tab.link,{name::'val1'}]">...</a>

编程式导航this.router.navigate(['home',tab.link,{name:'val1'}]);

  • URL

http://localhost:4200/home/sports;name=val1

  • 读取
    this.route.paramsMap.subscribe(params => {...});
  • snapshot (当不需要Observable时的替代品)
this.selectedId = this.route.snapshot.paramMap.get('id')
查询参数(路径中?后的字典值,可以和路径参数并存)
  • 配置

{path:'home',component:HomeContainerComponent}

  • 激活(路径参数+查询参数)

<a [routerLink]="['/home']" [queryParams]={name:'val1'}>...</a>

  • this.router.navigate(['home'],{queryParams:{name:'val1'}})
  • URL

http://localhost:4200/home?name=val1

  • 读取(区别于paramsMap)

this.route.queryParamsMap.subscribe(params => {...})

嵌套路由

通常一级路由是绝对路径,二级路由以下设置为相对路径

页面中可以有多个具名的router-outlet,但匿名的只能有一个
<a [routerLink]="['grand']" routerLinkActive="active" [queryParams]="{name:'zhangsan'}">
Link to grand</a>

<a [routerLink="[{outlets:{second:aux}}]"]>Link to Second</a>
<a [routerLink]="[{outlets:{popup:['second']}}]"></a>
<router-outlet></router-outlet>
<router-outlet name="second"></router-outlet>
const namedRoutes:Routes = [
    {
        path:'compose',
        component:ComposeMessageCompoent,
        outlet:'second'
    }
]
const routes:Routes = [
    {path:'',redirectTo:'/heroes',pathMatch:'full'},
    {path:'**',component:NotFoundComponent}
]
@NgModule({
    imports:[
        RouterModule.forRoot(routes.concat(namedRoutes))
    ]
})
路由守卫
<a routerLink="./" [routerLinkActiveOptions]="{exact : true}"></a>
//相当于全部匹配patchMatcher:'full'
  • CanActivate导航到某路由
ng g g router-study/auth

阻止进入到admin路由

const routes:Routes = [
    {
        path:'admin',
        component:AdminComponent,
        canActivate:[AuthGuard],
        children:[
            {
                path:'',
                children:[
                    {path:'crises',component:CrisesComponent},
                    {path:'heroes',component:HeroesComponent},
                    {path:'',component:DashboardComponent}
                ]
            }
        ]
    }
]

export class AuthGuard implements CanActivate{
    canActive(
        next:ActivatedRouteSnapshot,
        state:RouterStateSnapshot
    ):boolean {
        return true;
        //只有返回值为true时,路由才放行
    }
}
  • CanActivateChild导航到某子路由

阻止进入到children

const routes:Routes = [
    {
        path:'admin',
        component:AdminComponent,
        children:[
            {
                path:'',
                canActivate:[AuthGuard],
                children:[
                    {path:'crises',component:CrisesComponent},
                    {path:'heroes',component:HeroesComponent},
                    {path:'',component:DashboardComponent}
                ]
            }
        ]
    }
]
  • CanDeactivate从当前路由离开

返回true可以离开

export interface CanComponentDeactivate {
    canDeactivate:()=> Observale<boolean> | promise<boolean> | boolean;
}
export class CanDeactivateGuard implements CanDeactivate<CanComponentDeactive>{
    canDeactivate(component:CanComponentDeactivate){
        //return component.canDeactive ? component.canDeactive() : true;
        return component?.canDeactive()
    }
}
  • resolve守卫

保证了数据获取后再进行路由跳转,防止因数据延迟而出现的空组件情况,以此增强用户体验。

  • CanLoad来处理异步导航到某特性模块的情况
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 一:路由基础 什么是路由: 在web开发中,路由的概念由来已久,简而言之,就是利用URL的唯一性来指定特定的事物,...
    真的稻城阅读 6,036评论 2 7
  • 一、SPA的概念 首先明确一个概念,SPA,全称为Single Page Application单页应用,一个单页...
    耦耦阅读 5,996评论 0 3
  • 一、创建一个带路由的项目 可以选择跳过安装。这里我遇到了npm 安装失败的情况。尝试了很多种方法。cnpm方式不要...
    LH_0811阅读 422评论 0 0
  • 一.课程简介 (注意:这里的AngularJS指的是2.0以下的版本) AngularJS的优点: 模板功能强大丰...
    壹点微尘阅读 951评论 0 0
  • 1. 路由是什么 路由(导航)本质上是切换视图的一种机制 2.路由的导航的URL是否真实存在 angular的路...
    程序猿吴阅读 206评论 0 0