[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"knowledge-\u002Fapi\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Frouter":3,"knowledge-related-\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Frouter":1143,"knowledge-series-\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Frouter":1169},{"source":4,"connector":5,"page":6},"sqlite","better-sqlite3",{"path":7,"title":8,"description":9,"category":10,"tags":11,"date":14,"pinned":15,"draft":15,"body":16,"seo":1139,"stem":1140,"id":1141,"extension":1142},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Frouter","路由","Angular Router 是官方客户端路由模块，支持嵌套路由、懒加载、路由守卫与解析器。见 Angular 基础。","技能小册",[12,13],"angular","router","2023-02-04",false,{"type":17,"value":18,"toc":1131},"minimark",[19,22,38,42,414,459,462,527,618,621,802,852,855,985,1002,1006,1074,1077,1080,1127],[20,21,8],"h1",{"id":8},[23,24,25,32,33,37],"p",{},[26,27,31],"a",{"href":28,"rel":29},"https:\u002F\u002Fangular.dev\u002Fguide\u002Frouting",[30],"nofollow","Angular Router"," 是官方客户端路由模块，支持嵌套路由、懒加载、路由守卫与解析器。见 ",[26,34,36],{"href":35},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Fbasics","Angular 基础","。",[39,40,41],"h2",{"id":41},"配置路由",[43,44,49],"pre",{"className":45,"code":46,"language":47,"meta":48,"style":48},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark","\u002F\u002F app.routes.ts\nimport { Routes } from \"@angular\u002Frouter\";\n\nexport const routes: Routes = [\n  { path: \"\", redirectTo: \"home\", pathMatch: \"full\" },\n  { path: \"home\", loadComponent: () => import(\".\u002Fhome\u002Fhome.component\").then((m) => m.HomeComponent) },\n  {\n    path: \"admin\",\n    canActivate: [authGuard],\n    loadChildren: () => import(\".\u002Fadmin\u002Fadmin.routes\").then((m) => m.ADMIN_ROUTES),\n  },\n  { path: \"**\", loadComponent: () => import(\".\u002Fnot-found\u002Fnot-found.component\").then((m) => m.NotFoundComponent) },\n];\n","ts","",[50,51,52,61,96,103,130,177,251,257,275,288,338,344,406],"code",{"__ignoreMap":48},[53,54,57],"span",{"class":55,"line":56},"line",1,[53,58,60],{"class":59},"sutJx","\u002F\u002F app.routes.ts\n",[53,62,64,68,72,76,79,82,86,90,93],{"class":55,"line":63},2,[53,65,67],{"class":66},"sVHd0","import",[53,69,71],{"class":70},"sP7_E"," {",[53,73,75],{"class":74},"su5hD"," Routes",[53,77,78],{"class":70}," }",[53,80,81],{"class":66}," from",[53,83,85],{"class":84},"sjJ54"," \"",[53,87,89],{"class":88},"s_sjI","@angular\u002Frouter",[53,91,92],{"class":84},"\"",[53,94,95],{"class":70},";\n",[53,97,99],{"class":55,"line":98},3,[53,100,102],{"emptyLinePlaceholder":101},true,"\n",[53,104,106,109,113,117,121,124,127],{"class":55,"line":105},4,[53,107,108],{"class":66},"export",[53,110,112],{"class":111},"sbsja"," const",[53,114,116],{"class":115},"s_hVV"," routes",[53,118,120],{"class":119},"smGrS",":",[53,122,75],{"class":123},"sbgvK",[53,125,126],{"class":119}," =",[53,128,129],{"class":74}," [\n",[53,131,133,136,140,142,145,148,151,153,155,158,160,162,165,167,169,172,174],{"class":55,"line":132},5,[53,134,135],{"class":70},"  {",[53,137,139],{"class":138},"skxfh"," path",[53,141,120],{"class":70},[53,143,144],{"class":84}," \"\"",[53,146,147],{"class":70},",",[53,149,150],{"class":138}," redirectTo",[53,152,120],{"class":70},[53,154,85],{"class":84},[53,156,157],{"class":88},"home",[53,159,92],{"class":84},[53,161,147],{"class":70},[53,163,164],{"class":138}," pathMatch",[53,166,120],{"class":70},[53,168,85],{"class":84},[53,170,171],{"class":88},"full",[53,173,92],{"class":84},[53,175,176],{"class":70}," },\n",[53,178,180,182,184,186,188,190,192,194,198,200,203,206,209,212,214,217,219,222,225,228,230,232,236,238,240,243,245,248],{"class":55,"line":179},6,[53,181,135],{"class":70},[53,183,139],{"class":138},[53,185,120],{"class":70},[53,187,85],{"class":84},[53,189,157],{"class":88},[53,191,92],{"class":84},[53,193,147],{"class":70},[53,195,197],{"class":196},"sGLFI"," loadComponent",[53,199,120],{"class":70},[53,201,202],{"class":70}," ()",[53,204,205],{"class":111}," =>",[53,207,208],{"class":119}," import",[53,210,211],{"class":74},"(",[53,213,92],{"class":84},[53,215,216],{"class":88},".\u002Fhome\u002Fhome.component",[53,218,92],{"class":84},[53,220,221],{"class":74},")",[53,223,224],{"class":70},".",[53,226,227],{"class":196},"then",[53,229,211],{"class":74},[53,231,211],{"class":70},[53,233,235],{"class":234},"s99_P","m",[53,237,221],{"class":70},[53,239,205],{"class":111},[53,241,242],{"class":74}," m",[53,244,224],{"class":70},[53,246,247],{"class":74},"HomeComponent) ",[53,249,250],{"class":70},"},\n",[53,252,254],{"class":55,"line":253},7,[53,255,256],{"class":70},"  {\n",[53,258,260,263,265,267,270,272],{"class":55,"line":259},8,[53,261,262],{"class":138},"    path",[53,264,120],{"class":70},[53,266,85],{"class":84},[53,268,269],{"class":88},"admin",[53,271,92],{"class":84},[53,273,274],{"class":70},",\n",[53,276,278,281,283,286],{"class":55,"line":277},9,[53,279,280],{"class":138},"    canActivate",[53,282,120],{"class":70},[53,284,285],{"class":74}," [authGuard]",[53,287,274],{"class":70},[53,289,291,294,296,298,300,302,304,306,309,311,313,315,317,319,321,323,325,327,329,331,334,336],{"class":55,"line":290},10,[53,292,293],{"class":196},"    loadChildren",[53,295,120],{"class":70},[53,297,202],{"class":70},[53,299,205],{"class":111},[53,301,208],{"class":119},[53,303,211],{"class":74},[53,305,92],{"class":84},[53,307,308],{"class":88},".\u002Fadmin\u002Fadmin.routes",[53,310,92],{"class":84},[53,312,221],{"class":74},[53,314,224],{"class":70},[53,316,227],{"class":196},[53,318,211],{"class":74},[53,320,211],{"class":70},[53,322,235],{"class":234},[53,324,221],{"class":70},[53,326,205],{"class":111},[53,328,242],{"class":74},[53,330,224],{"class":70},[53,332,333],{"class":115},"ADMIN_ROUTES",[53,335,221],{"class":74},[53,337,274],{"class":70},[53,339,341],{"class":55,"line":340},11,[53,342,343],{"class":70},"  },\n",[53,345,347,349,351,353,355,358,360,362,364,366,368,370,372,374,376,379,381,383,385,387,389,391,393,395,397,399,401,404],{"class":55,"line":346},12,[53,348,135],{"class":70},[53,350,139],{"class":138},[53,352,120],{"class":70},[53,354,85],{"class":84},[53,356,357],{"class":88},"**",[53,359,92],{"class":84},[53,361,147],{"class":70},[53,363,197],{"class":196},[53,365,120],{"class":70},[53,367,202],{"class":70},[53,369,205],{"class":111},[53,371,208],{"class":119},[53,373,211],{"class":74},[53,375,92],{"class":84},[53,377,378],{"class":88},".\u002Fnot-found\u002Fnot-found.component",[53,380,92],{"class":84},[53,382,221],{"class":74},[53,384,224],{"class":70},[53,386,227],{"class":196},[53,388,211],{"class":74},[53,390,211],{"class":70},[53,392,235],{"class":234},[53,394,221],{"class":70},[53,396,205],{"class":111},[53,398,242],{"class":74},[53,400,224],{"class":70},[53,402,403],{"class":74},"NotFoundComponent) ",[53,405,250],{"class":70},[53,407,409,412],{"class":55,"line":408},13,[53,410,411],{"class":74},"]",[53,413,95],{"class":70},[43,415,417],{"className":45,"code":416,"language":47,"meta":48,"style":48},"bootstrapApplication(AppComponent, {\n  providers: [provideRouter(routes)],\n});\n",[50,418,419,432,450],{"__ignoreMap":48},[53,420,421,424,427,429],{"class":55,"line":56},[53,422,423],{"class":196},"bootstrapApplication",[53,425,426],{"class":74},"(AppComponent",[53,428,147],{"class":70},[53,430,431],{"class":70}," {\n",[53,433,434,437,439,442,445,448],{"class":55,"line":63},[53,435,436],{"class":138},"  providers",[53,438,120],{"class":70},[53,440,441],{"class":74}," [",[53,443,444],{"class":196},"provideRouter",[53,446,447],{"class":74},"(routes)]",[53,449,274],{"class":70},[53,451,452,455,457],{"class":55,"line":98},[53,453,454],{"class":70},"}",[53,456,221],{"class":74},[53,458,95],{"class":70},[39,460,461],{"id":461},"模板导航",[43,463,467],{"className":464,"code":465,"language":466,"meta":48,"style":48},"language-html shiki shiki-themes material-theme-lighter github-light github-dark","\u003Ca routerLink=\"\u002Fhome\" routerLinkActive=\"active\">首页\u003C\u002Fa>\n\u003Crouter-outlet \u002F>\n","html",[50,468,469,517],{"__ignoreMap":48},[53,470,471,474,477,481,484,486,489,491,494,496,498,501,503,506,509,512,514],{"class":55,"line":56},[53,472,473],{"class":70},"\u003C",[53,475,26],{"class":476},"sQzsp",[53,478,480],{"class":479},"s9AJx"," routerLink",[53,482,483],{"class":70},"=",[53,485,92],{"class":84},[53,487,488],{"class":88},"\u002Fhome",[53,490,92],{"class":84},[53,492,493],{"class":479}," routerLinkActive",[53,495,483],{"class":70},[53,497,92],{"class":84},[53,499,500],{"class":88},"active",[53,502,92],{"class":84},[53,504,505],{"class":70},">",[53,507,508],{"class":74},"首页",[53,510,511],{"class":70},"\u003C\u002F",[53,513,26],{"class":476},[53,515,516],{"class":70},">\n",[53,518,519,521,524],{"class":55,"line":63},[53,520,473],{"class":70},[53,522,523],{"class":476},"router-outlet",[53,525,526],{"class":70}," \u002F>\n",[43,528,530],{"className":45,"code":529,"language":47,"meta":48,"style":48},"import { Router } from \"@angular\u002Frouter\";\n\nconstructor(private router: Router) {}\n\ngoLogin() {\n  this.router.navigate([\"\u002Flogin\"]);\n}\n",[50,531,532,553,557,568,572,583,613],{"__ignoreMap":48},[53,533,534,536,538,541,543,545,547,549,551],{"class":55,"line":56},[53,535,67],{"class":66},[53,537,71],{"class":70},[53,539,540],{"class":74}," Router",[53,542,78],{"class":70},[53,544,81],{"class":66},[53,546,85],{"class":84},[53,548,89],{"class":88},[53,550,92],{"class":84},[53,552,95],{"class":70},[53,554,555],{"class":55,"line":63},[53,556,102],{"emptyLinePlaceholder":101},[53,558,559,562,565],{"class":55,"line":98},[53,560,561],{"class":196},"constructor",[53,563,564],{"class":74},"(private router: Router) ",[53,566,567],{"class":70},"{}\n",[53,569,570],{"class":55,"line":105},[53,571,102],{"emptyLinePlaceholder":101},[53,573,574,577,580],{"class":55,"line":132},[53,575,576],{"class":196},"goLogin",[53,578,579],{"class":74},"() ",[53,581,582],{"class":70},"{\n",[53,584,585,589,591,593,595,598,601,603,606,608,611],{"class":55,"line":179},[53,586,588],{"class":587},"s39Yj","  this",[53,590,224],{"class":70},[53,592,13],{"class":74},[53,594,224],{"class":70},[53,596,597],{"class":196},"navigate",[53,599,600],{"class":138},"([",[53,602,92],{"class":84},[53,604,605],{"class":88},"\u002Flogin",[53,607,92],{"class":84},[53,609,610],{"class":138},"])",[53,612,95],{"class":70},[53,614,615],{"class":55,"line":253},[53,616,617],{"class":70},"}\n",[39,619,620],{"id":620},"路由守卫",[43,622,624],{"className":45,"code":623,"language":47,"meta":48,"style":48},"import { CanActivateFn, Router } from \"@angular\u002Frouter\";\nimport { inject } from \"@angular\u002Fcore\";\n\nexport const authGuard: CanActivateFn = () => {\n  const router = inject(Router);\n  const isLoggedIn = false; \u002F\u002F 示例：应改为 AuthService 的实际逻辑\n  if (!isLoggedIn) {\n    return router.createUrlTree([\"\u002Flogin\"]);\n  }\n  return true;\n};\n",[50,625,626,651,673,677,699,720,739,758,782,787,797],{"__ignoreMap":48},[53,627,628,630,632,635,637,639,641,643,645,647,649],{"class":55,"line":56},[53,629,67],{"class":66},[53,631,71],{"class":70},[53,633,634],{"class":74}," CanActivateFn",[53,636,147],{"class":70},[53,638,540],{"class":74},[53,640,78],{"class":70},[53,642,81],{"class":66},[53,644,85],{"class":84},[53,646,89],{"class":88},[53,648,92],{"class":84},[53,650,95],{"class":70},[53,652,653,655,657,660,662,664,666,669,671],{"class":55,"line":63},[53,654,67],{"class":66},[53,656,71],{"class":70},[53,658,659],{"class":74}," inject",[53,661,78],{"class":70},[53,663,81],{"class":66},[53,665,85],{"class":84},[53,667,668],{"class":88},"@angular\u002Fcore",[53,670,92],{"class":84},[53,672,95],{"class":70},[53,674,675],{"class":55,"line":98},[53,676,102],{"emptyLinePlaceholder":101},[53,678,679,681,683,687,689,691,693,695,697],{"class":55,"line":105},[53,680,108],{"class":66},[53,682,112],{"class":111},[53,684,686],{"class":685},"sfCm-"," authGuard",[53,688,120],{"class":119},[53,690,634],{"class":123},[53,692,126],{"class":119},[53,694,202],{"class":70},[53,696,205],{"class":111},[53,698,431],{"class":70},[53,700,701,704,707,709,711,713,716,718],{"class":55,"line":132},[53,702,703],{"class":111},"  const",[53,705,706],{"class":115}," router",[53,708,126],{"class":119},[53,710,659],{"class":196},[53,712,211],{"class":138},[53,714,715],{"class":74},"Router",[53,717,221],{"class":138},[53,719,95],{"class":70},[53,721,722,724,727,729,733,736],{"class":55,"line":179},[53,723,703],{"class":111},[53,725,726],{"class":115}," isLoggedIn",[53,728,126],{"class":119},[53,730,732],{"class":731},"syTEX"," false",[53,734,735],{"class":70},";",[53,737,738],{"class":59}," \u002F\u002F 示例：应改为 AuthService 的实际逻辑\n",[53,740,741,744,747,750,753,756],{"class":55,"line":253},[53,742,743],{"class":66},"  if",[53,745,746],{"class":138}," (",[53,748,749],{"class":119},"!",[53,751,752],{"class":74},"isLoggedIn",[53,754,755],{"class":138},") ",[53,757,582],{"class":70},[53,759,760,763,765,767,770,772,774,776,778,780],{"class":55,"line":259},[53,761,762],{"class":66},"    return",[53,764,706],{"class":74},[53,766,224],{"class":70},[53,768,769],{"class":196},"createUrlTree",[53,771,600],{"class":138},[53,773,92],{"class":84},[53,775,605],{"class":88},[53,777,92],{"class":84},[53,779,610],{"class":138},[53,781,95],{"class":70},[53,783,784],{"class":55,"line":277},[53,785,786],{"class":70},"  }\n",[53,788,789,792,795],{"class":55,"line":290},[53,790,791],{"class":66},"  return",[53,793,794],{"class":731}," true",[53,796,95],{"class":70},[53,798,799],{"class":55,"line":340},[53,800,801],{"class":70},"};\n",[803,804,805,818],"table",{},[806,807,808],"thead",{},[809,810,811,815],"tr",{},[812,813,814],"th",{},"守卫",[812,816,817],{},"时机",[819,820,821,832,842],"tbody",{},[809,822,823,829],{},[824,825,826],"td",{},[50,827,828],{},"canActivate",[824,830,831],{},"进入路由前",[809,833,834,839],{},[824,835,836],{},[50,837,838],{},"canDeactivate",[824,840,841],{},"离开路由前（如未保存提示）",[809,843,844,849],{},[824,845,846],{},[50,847,848],{},"canMatch",[824,850,851],{},"是否匹配该路由配置",[39,853,854],{"id":854},"路由参数",[43,856,858],{"className":45,"code":857,"language":47,"meta":48,"style":48},"import { ActivatedRoute } from \"@angular\u002Frouter\";\n\n\u002F\u002F 快照（仅初始化读一次）\nconst id = this.route.snapshot.paramMap.get(\"id\");\n\n\u002F\u002F 可观察（参数变化时更新）\nthis.route.paramMap.subscribe((params) => { ... });\n",[50,859,860,881,885,890,936,940,945],{"__ignoreMap":48},[53,861,862,864,866,869,871,873,875,877,879],{"class":55,"line":56},[53,863,67],{"class":66},[53,865,71],{"class":70},[53,867,868],{"class":74}," ActivatedRoute",[53,870,78],{"class":70},[53,872,81],{"class":66},[53,874,85],{"class":84},[53,876,89],{"class":88},[53,878,92],{"class":84},[53,880,95],{"class":70},[53,882,883],{"class":55,"line":63},[53,884,102],{"emptyLinePlaceholder":101},[53,886,887],{"class":55,"line":98},[53,888,889],{"class":59},"\u002F\u002F 快照（仅初始化读一次）\n",[53,891,892,895,898,900,903,905,908,910,913,915,918,920,923,925,927,930,932,934],{"class":55,"line":105},[53,893,894],{"class":111},"const",[53,896,897],{"class":115}," id",[53,899,126],{"class":119},[53,901,902],{"class":587}," this",[53,904,224],{"class":70},[53,906,907],{"class":74},"route",[53,909,224],{"class":70},[53,911,912],{"class":74},"snapshot",[53,914,224],{"class":70},[53,916,917],{"class":74},"paramMap",[53,919,224],{"class":70},[53,921,922],{"class":196},"get",[53,924,211],{"class":74},[53,926,92],{"class":84},[53,928,929],{"class":88},"id",[53,931,92],{"class":84},[53,933,221],{"class":74},[53,935,95],{"class":70},[53,937,938],{"class":55,"line":132},[53,939,102],{"emptyLinePlaceholder":101},[53,941,942],{"class":55,"line":179},[53,943,944],{"class":59},"\u002F\u002F 可观察（参数变化时更新）\n",[53,946,947,950,952,954,956,958,960,963,965,967,970,972,974,976,979,981,983],{"class":55,"line":253},[53,948,949],{"class":587},"this",[53,951,224],{"class":70},[53,953,907],{"class":74},[53,955,224],{"class":70},[53,957,917],{"class":74},[53,959,224],{"class":70},[53,961,962],{"class":196},"subscribe",[53,964,211],{"class":74},[53,966,211],{"class":70},[53,968,969],{"class":234},"params",[53,971,221],{"class":70},[53,973,205],{"class":111},[53,975,71],{"class":70},[53,977,978],{"class":119}," ...",[53,980,78],{"class":70},[53,982,221],{"class":74},[53,984,95],{"class":70},[23,986,987,988,991,992,995,996,1001],{},"Signal 路由输入：",[50,989,990],{},"withComponentInputBinding()"," 可将路由参数绑定到 ",[50,993,994],{},"input()","（见 ",[26,997,1000],{"href":998,"rel":999},"https:\u002F\u002Fangular.dev\u002Fguide\u002Frouting\u002Fcommon-router-tasks#setting-up-routerlink-directives",[30],"官方路由指南","）。",[39,1003,1005],{"id":1004},"与-vue-react-router-对照","与 Vue \u002F React Router 对照",[803,1007,1008,1023],{},[806,1009,1010],{},[809,1011,1012,1014,1017,1020],{},[812,1013],{},[812,1015,1016],{},"Angular",[812,1018,1019],{},"Vue Router",[812,1021,1022],{},"React Router",[819,1024,1025,1045],{},[809,1026,1027,1030,1035,1040],{},[824,1028,1029],{},"出口",[824,1031,1032],{},[50,1033,1034],{},"\u003Crouter-outlet>",[824,1036,1037],{},[50,1038,1039],{},"\u003CRouterView>",[824,1041,1042],{},[50,1043,1044],{},"\u003COutlet \u002F>",[809,1046,1047,1050,1059,1065],{},[824,1048,1049],{},"懒加载",[824,1051,1052,1055,1056],{},[50,1053,1054],{},"loadComponent"," \u002F ",[50,1057,1058],{},"loadChildren",[824,1060,1061,1062],{},"动态 ",[50,1063,1064],{},"import()",[824,1066,1067,1070,1071],{},[50,1068,1069],{},"lazy()"," + ",[50,1072,1073],{},"Suspense",[39,1075,1076],{"id":1076},"参考文献",[23,1078,1079],{},"以下链接在编写时均可正常访问：",[803,1081,1082,1092],{},[806,1083,1084],{},[809,1085,1086,1089],{},[812,1087,1088],{},"资料",[812,1090,1091],{},"说明",[819,1093,1094,1105,1116],{},[809,1095,1096,1102],{},[824,1097,1098],{},[26,1099,1101],{"href":28,"rel":1100},[30],"路由与导航",[824,1103,1104],{},"官方",[809,1106,1107,1113],{},[824,1108,1109],{},[26,1110,620],{"href":1111,"rel":1112},"https:\u002F\u002Fangular.dev\u002Fguide\u002Frouting\u002Fcommon-router-tasks#preventing-unauthorized-access",[30],[824,1114,1115],{},"鉴权",[809,1117,1118,1124],{},[824,1119,1120],{},[26,1121,1049],{"href":1122,"rel":1123},"https:\u002F\u002Fangular.dev\u002Fguide\u002Frouting\u002Fcommon-router-tasks#lazy-loading",[30],[824,1125,1126],{},"代码分割",[1128,1129,1130],"style",{},"html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sQzsp, html code.shiki .sQzsp{--shiki-light:#E53935;--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .s9AJx, html code.shiki .s9AJx{--shiki-light:#9C3EDA;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s39Yj, html code.shiki .s39Yj{--shiki-light:#39ADB5;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sfCm-, html code.shiki .sfCm-{--shiki-light:#90A4AE;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":48,"searchDepth":63,"depth":63,"links":1132},[1133,1134,1135,1136,1137,1138],{"id":41,"depth":63,"text":41},{"id":461,"depth":63,"text":461},{"id":620,"depth":63,"text":620},{"id":854,"depth":63,"text":854},{"id":1004,"depth":63,"text":1005},{"id":1076,"depth":63,"text":1076},{"title":8,"description":9},"knowledge\u002Fbooklet\u002Fframe\u002FAngular\u002Frouter","knowledge\u002Fknowledge\u002Fbooklet\u002Fframe\u002FAngular\u002Frouter.md","md",{"items":1144},[1145,1149,1153,1157,1161,1165],{"path":1146,"title":1147,"description":1148,"category":10,"score":179},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Fecology","生态集成","Angular 官方维护路由、HTTP、表单、动画等；UI 与状态扩展由社区与官方 Material 团队提供。涵盖官方\u002F半官方库、常用第三方库、与 Vue\u002FReact 生态对照、选型建议与常见坑。",{"path":1150,"title":1151,"description":1152,"category":10,"score":179},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Fsignals\u002Fbasics","Signal 基础","Signals 是 Angular 16 引入的响应式原语：可读写的 signal、派生的 computed、副作用 effect。用于组件内状态与跨组件细粒度更新，涵盖 API、input signal、与变更检测的关系、最佳实践与常见坑。",{"path":1154,"title":1155,"description":1156,"category":10,"score":179},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Fsignals\u002Frxjs","RxJS 互操作","Angular 内置 RxJS 处理异步流（HTTP、HttpClient、路由事件、FormControl 的 valueChanges 等）。Signal 适合同步\u002F短链路状态；长生命周期流仍常用 Observable。涵盖 async 管道、toSignal\u002FtoObservable、常用操作符、最佳实践与常见坑。",{"path":1158,"title":1159,"description":1160,"category":10,"score":179},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Fforms","表单","Angular 提供 响应式表单（Reactive Forms） 与 模板驱动表单（Template-driven）。复杂表单推荐 Reactive Forms（模型在 TypeScript 中，易测试）。涵盖 FormGroup\u002FFormArray、Typed Forms、自定义校验器、最佳实践与常见坑。",{"path":1162,"title":1163,"description":1164,"category":10,"score":179},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Fstate","状态管理","Angular 没有强制单一状态库：服务 + DI、Signal、RxJS 即可覆盖多数场景；大型应用可选用 NgRx。涵盖选型、服务作为状态容器、跨组件共享、NgRx 与 SignalStore、常见坑。",{"path":1166,"title":1167,"description":1168,"category":10,"score":179},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Fhttp","HTTP 与数据","Angular 通过 HttpClient（@angular\u002Fcommon\u002Fhttp）发起 HTTP 请求，返回 RxJS Observable。见 RxJS 互操作、依赖注入。",{"series":1170,"title":12,"items":1171,"index":277,"prev":1211,"next":1212},"booklet\u002Fframe\u002Fangular",[1172,1174,1176,1180,1184,1188,1190,1192,1194,1198,1199,1203,1205,1207],{"path":35,"title":36,"date":1173,"pinned":15},"2020-03-07",{"path":1150,"title":1151,"date":1175,"pinned":15},"2026-06-12",{"path":1177,"title":1178,"date":1179,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Fperformance\u002Fchange-detection","变更检测","2023-10-12",{"path":1181,"title":1182,"date":1183,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Fcomponents","组件与模板","2021-07-11",{"path":1185,"title":1186,"date":1187,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Fdi","依赖注入","2021-01-24",{"path":1146,"title":1147,"date":1189,"pinned":15},"2026-07-12",{"path":1158,"title":1159,"date":1191,"pinned":15},"2025-05-26",{"path":1166,"title":1167,"date":1193,"pinned":15},"2024-12-27",{"path":1195,"title":1196,"date":1197,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Fproject","工程化","2021-09-01",{"path":7,"title":8,"date":14,"pinned":15},{"path":1200,"title":1201,"date":1202,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Fperformance\u002Fruntime","运行时优化","2022-11-01",{"path":1154,"title":1155,"date":1204,"pinned":15},"2026-04-06",{"path":1162,"title":1163,"date":1206,"pinned":15},"2025-04-29",{"path":1208,"title":1209,"date":1210,"pinned":15},"\u002Fknowledge\u002Fbooklet\u002Fframe\u002Fangular\u002Ftest","测试","2021-08-25",{"path":1195,"title":1196,"date":1197,"pinned":15},{"path":1200,"title":1201,"date":1202,"pinned":15}]