Angular Router 是 Angular 最重要的内置模块之一。
利用它可以非常快速的生成路由规则,实现前端的模块化开发。
但是其中有一些细节值得关注。
在本篇文章中,我会重点介绍 Angular Router 中——路由匹配的概念。
匹配原理
Angular 在匹配路由中的各个路径( path )的时候,
都会根据 ‘/’ ,把 URL拆解成一个 prefix 片和剩余 URL 片。
其中默认匹配算法,一旦 prefix 片与当前路径匹配,就能继续路由。
例子
假设我们在代码中定义了这样一个路由。
const routes: Routes = [
{ path: 'profile', component: ProfileComponent,
children:[
{ path: 'child', component: ProfileChildComponent},
]
},
{ path: 'home', component: HomeComponent},
{ path: '', pathMatch: 'prefix', redirectTo: '/home'},
{ path: '**', redirectTo: '/profile'},
];
当 Auglar 在处理URL—— ‘profile/child’时,
URL 总会被拆解成 ‘profile’(当做 prefix 片)和 ‘child’(剩余 URL 片)。
在默认 prefix 算法下,
Angular 会根据 prefix 片(’profile’)匹配到 ‘profile’ 这个路径,
并将剩余 URL —— ‘child’ 传入子路由,直到子路由也匹配成功。
这里就是一个 prefix 的例子。
陷阱
让我们在回过头来看看这个路由,重点关注 redirectTo 这个参数。
假如我们想让网页在空 URL 的时候显示 home 组件的内容,
且在其他 URL 的时候比如(@#@@/mistake/wrong )显示 profile 组件,
那么,上面定义的路由就会有一些问题。
const routes: Routes = [
...
{ path: '', pathMatch: 'prefix', redirectTo: '/home'},
{ path: '**', redirectTo: '/profile'},
...
];
可以看到,我输入一串无意义的 URL 之后,页面并没有如期跳转到 profile ,
而是仍然跳转到了 home 组件。
这是因为空字符 ” 十分特殊,它是任何 URL 的 prefix,
在此情况下,若还是采用 prefix 进行匹配,
那任何无意义的路由都会匹配到这个空路径,从而导致结果与预期不符。
prefix 算法下,一旦 prefix 片与当前路径匹配,就能继续路由。
例子
为了解决这个问题,我们只需把匹配规则改成 ‘full’ 即可。
它会将当前路径下待处理的 URL 片作为一个整体,
与当前到达的路径进行比较。
让我们来看修改过的这个例子:
const routes: Routes = [
...
{ path: '', pathMatch: 'full', redirectTo: '/home'},
{ path: '**', redirectTo: '/profile'},
...
];
假设现在有 URL—— @#@@ /mistake/wrong,到达路径 ” 时,
URL 会被切分成 ‘@#@@’ (prefix)和 ‘mistake/wrong ‘ (剩余URL)。
‘full’ 匹配算法会将待处理的 URL ——@#@@/mistake/wrong,
当做整体与空路径进行比较。
如此一来,那些无意义的路径就无法与空路径相匹配。
参考文献
Angular Router Set Up Redirects
ANGULAR ROUTER: EMPTY PATHS, COMPONENTLESS ROUTES, AND REDIRECTS
The Three Pillars of the Angular Router — Router States and URL Matching