路由簡單路由案例默認路由動態路由動態路由的JS跳轉普通跳轉get傳值父子路由模塊自定義模塊添加自定義模塊添加自定義模塊下的組件添加自定義模塊下的服務路由配置問題記錄自定義模塊路由配置懶加載時報錯參考文獻javascript
一、命令建立項目css
ng new angualrdemo04
複製代碼
執行該命令時,會有這麼一段內容詢問你是否須要建立路由。html
Would you like to add Angular routing? (y/N)
複製代碼
輸入 y 即可給項目中增長路由設置,新建的項目文件結構以下:java
查看 app-routing.module.ts 文件內容:nginx
import {NgModule} from '@angular/core';
import {Routes, RouterModule} from '@angular/router';
const routes: Routes = [];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule {
}
複製代碼
接着咱們建立幾個組件。web
二、建立組件編程
ng g component components/product
ng g component components/news
ng g component components/home
複製代碼
三、在 app-routing.module.ts 配置路由,根據不一樣的 URL, 跳轉到不一樣的頁面 promise
import {NewsComponent} from './components/news/news.component';
import {HomeComponent} from './components/home/home.component';
import {ProductComponent} from './components/product/product.component';
const routes: Routes = [
{
path: 'home', component: HomeComponent
},
{
path: 'news', component: NewsComponent
},
{
path: 'product', component: ProductComponent
}
];
複製代碼
四、app.component.html 根組件模板,配置 router-outlet 顯示動態加載的路由ruby
<header class="header">
<a [routerLink]="[ '/home' ]" routerLinkActive="active">首頁</a>
<a [routerLink]="[ '/news' ]" routerLinkActive="active">新聞</a>
<a [routerLink]="[ '/product' ]" routerLinkActive="active-link">商品</a>
</header>
<router-outlet></router-outlet>
複製代碼
五、app.component.css 配置樣式app
.header{
height: 44px;
line-height: 44px;
background-color: black;
}
.header a{
color: #ffffff;
padding: 10px 40px;
}
.header .active {
color: red;
}
.header .active-link{
color: orange;
}
複製代碼
六、頁面測試
七、小結
routerLink 裏面用到的 path 就是在 app-routing.module.ts 裏配置的,routerLinkActive 做用是當此連接指向的路由激活時,該指令就會往宿主元素上添加一個 CSS 類。
<router-outlet></router-outlet>
能夠簡單把它理解爲: 頁面的佔位符,動態加載,會被替換掉的。
當點擊 home、about、 dashboard 時, 在導航欄的下方,會被對應的 XX.component.html 替換掉。
關於 <router-outlet>
的講解能夠參看: 幹什麼用的?
當啓動項目時,會默認打開連接 http://localhost:4200/ ,可是該頁面沒有任何信息,所以咱們設置該連接默認打開 home 頁面。
在 app-routing.module.ts 配置默認路由,如下兩種配置方式均可以,可是必須在最後位置。
const routes: Routes = [
{
path: 'home', component: HomeComponent
},
{
path: 'news', component: NewsComponent
},
{
path: 'product', component: ProductComponent
},
{
path: '**', component: HomeComponent
// path: '**', redirectTo: 'home'
}
];
複製代碼
還有一種方式,配置能夠在任意位置,我的習慣放在首位。
const routes: Routes = [
{
path: '', redirectTo: 'home', pathMatch: 'full'
}
{
path: 'home', component: HomeComponent
},
{
path: 'news', component: NewsComponent
},
{
path: 'product', component: ProductComponent
}
];
複製代碼
重定向路由須要一個 pathMatch
屬性,來告訴路由器如何用 URL 去匹配路由的路徑,不然路由器就會報錯。 在本應用中,路由器應該只有在完整的 URL等於 ''
時才選擇 HeroListComponent
組件,所以要把 pathMatch
設置爲 'full'
。
對於上文中的 news 組件,咱們新建一個 news-detail 組件,用來顯示新聞詳情。
一、配置動態路由
const routes: Routes = [
{
path: '', redirectTo: 'home', pathMatch: 'full'
},
{
path: 'home', component: HomeComponent
},
{
path: 'news', component: NewsComponent
},
{
path: 'newsDetail/:id', component: NewsDetailComponent
},
{
path: 'product', component: ProductComponent
},
];
複製代碼
二、news.component.ts
nums: any[] = [];
constructor() {
}
ngOnInit(): void {
for (let i = 0; i < 10; i++) {
this.nums.push('這是第' + i + '條新聞');
}
}
複製代碼
三、news.component.html
<p>news works!</p>
<ul>
<li *ngFor="let item of nums, let key = index"> -->
<!-- <a [routerLink]="['/newsDetail',key]" >{{key}} ---- {{item}}</a> -->
<a routerLink="/newsDetail/{{key}}" >{{key}} ---- {{item}}</a>
</li>
</ul>
複製代碼
上述兩種連接方式都是正確的,routerLink="xxxx",表示靜態連接,另外一種則表示動態連接,能夠經過動態值來生成連接。
四、在 news-detail.component.ts 獲取動態路由的值
import {ActivatedRoute} from '@angular/router';
export class NewsDetailComponent implements OnInit {
constructor(public router: ActivatedRoute) {
}
ngOnInit(): void {
this.router.params.subscribe((data) => {
console.log(data);
});
}
}
複製代碼
五、頁面測試
一、同新建 NewsDetail 組件同樣,再新建一個 ProductDetail 組件。
二、product.component.html
<button (click)="getProduct()">js跳轉到商品詳情頁面</button>
<button (click)="getHome()">js跳轉到主頁面</button>
複製代碼
三、product.component.ts
import { Router } from '@angular/router';
export class ProductComponent implements OnInit {
constructor(public router: Router) {
}
getProduct() {
this.router.navigate(['/productDetail/', '123']);
}
getHome() {
this.router.navigate(['/home']);
}
}
複製代碼
三、頁面測試
一、product.component.html
<button (click)="getNews()">js關於get傳值</button>
複製代碼
二、在 product.component.ts 額外引入 NavigationExtras
import {Component, OnInit} from '@angular/core';
import {Router, NavigationExtras} from '@angular/router';
export class ProductComponent implements OnInit {
constructor(public router: Router) {
}
getNews() {
let params: NavigationExtras = {
queryParams: {
'aid': '123'
}
};
this.router.navigate(['/news'],params);
}
}
複製代碼
三、在 news 組件中獲取 get 傳值
constructor(public router: ActivatedRoute) {
console.log(this.router.queryParams);
}
複製代碼
四、頁面測試
在網上衝浪時能夠常常看到點擊頭部頁面按鈕,主頁會
一、新建組件
ng g component components/home
ng g component components/home/welcome
ng g component components/home/setting
ng g component components/product
ng g component components/product/pcate
ng g component components/product/plist
複製代碼
二、配置路由
import {HomeComponent} from './components/home/home.component';
import {ProductComponent} from './components/product/product.component';
import {WelcomeComponent} from './components/home/welcome/welcome.component';
import {SettingComponent} from './components/home/setting/setting.component';
import {PcateComponent} from './components/product/pcate/pcate.component';
import {PlistComponent} from './components/product/plist/plist.component';
const routes: Routes = [
{
path: 'home', component: HomeComponent,
children:[
{
path:'welcome',component:WelcomeComponent
},
{
path:'setting',component:SettingComponent
},
{
path:'**',component:WelcomeComponent
}
]
},
{
path: 'product', component: ProductComponent,
children:[
{
path:'pcate',component:PcateComponent
},
{
path:'plist',component:PlistComponent
},
{
path:'**',component:PlistComponent
}
]
},
{
path: '**', component: HomeComponent
}
];
複製代碼
三、app.component.html
<header class="header">
<a [routerLink]="[ '/home' ]" routerLinkActive="active">首頁</a>
<a [routerLink]="[ '/product' ]" routerLinkActive="active">商品</a>
</header>
<router-outlet></router-outlet>
複製代碼
四、home.component.html
<div class="content">
<div class="left">
<a [routerLink]="['/home/welcome']" >歡迎首頁</a>
<br>
<br>
<a [routerLink]="['/home/setting']" >系統設置</a>
</div>
<div class="right">
<router-outlet></router-outlet>
</div>
</div>
複製代碼
五、style.css
.content{
width: 100%;
height: 400px;
display: flex;
}
.left{
padding: 20px 20px;
width: 200px;
border-right: 1px black solid;
height: 400px;
}
.right{
flex: 1px;
}
複製代碼
六、頁面測試
七、小結
根據測試結果可知,當點擊按鈕進行頁面跳轉時,頁面不須要刷新,網址發生改變便可。
Angular 內置模塊
當咱們項目比較小的時候能夠不用自定義模塊。 可是當咱們項目很是龐大的時候把全部的組
件都掛載到根模塊裏面不是特別合適。 因此這個時候咱們就能夠自定義模塊來組織咱們的項
目。
接下來咱們新建一個項目 angularDemo07,而後添加自定義模塊。
ng g module module/user
//若是須要添加路由,則在新建模塊時執行下面命令。
ng g module module/user --routing
ng g component module/user
複製代碼
查看上圖能夠發現,user 模塊和項目自帶的 app 模塊結構一致,只是少了路由配置文件。接着咱們在 user 模塊中新建組件。
ng g component module/user/components/profile
ng g component module/user/components/address
ng g component module/user/components/order
複製代碼
新建完成的項目結構如圖所示:
咱們查看 user.module.ts 文件內容:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { UserComponent } from './user.component';
import { ProfileComponent } from './components/profile/profile.component';
import { AddressComponent } from './components/address/address.component';
import { OrderComponent } from './components/order/order.component';
@NgModule({
declarations: [UserComponent, ProfileComponent, AddressComponent, OrderComponent],
imports: [
CommonModule
]
})
export class UserModule { }
複製代碼
若是想要訪問 user 組件,必需要在 user 模塊中將該組件暴露出來。修改 user.module.ts 文件:
@NgModule({
// user模塊裏的組件
declarations: [UserComponent, ProfileComponent, AddressComponent, OrderComponent],
// 暴露組件,讓其被其餘模塊所訪問
exports: [UserComponent],
imports: [
CommonModule
]
})
複製代碼
而後在根模塊中引入 user 模塊。
import {UserModule} from './module/user/user.module';
imports: [
BrowserModule,
AppRoutingModule,
UserModule
],
複製代碼
最後在 app.component.html 文件中添加 user 組件,便可看到 user.component.html 中的內容。
<h2>app組件</h2>
<app-user></app-user>
複製代碼
假設想要訪問 user 模塊下的 order 組件,則必須先將其暴露,才能夠在 app.component.html 中訪問。
ng g service module/user/services/common
複製代碼
而後在 user 模塊中引入該服務。
import {CommonService} from './services/common.service';
providers:[CommonService]
複製代碼
同理咱們再建立一個 product 模塊,以及它下面的組件。
ng g module module/product --routing
ng g component module/product
ng g component module/product/components/plist
ng g component module/product/components/pinfo
複製代碼
經過配置路由,能夠實現懶加載,從而沒必要在 app.module.ts 文件中引入自定義模塊,就能夠訪問自定義模塊下的組件內容。
一、首先在 app-routing.module.ts 文件中配置路由
const routes: Routes = [
// { path: 'user', loadChildren: './module/user/user.module#UserModule'},
// 更改路徑無效
// { path: 'user', loadChildren: 'src/app/module/user/user.module#UserModule'},
{ path: 'user', loadChildren: () => import('./module/user/user.module').then(m => m.UserModule) },
// { path: 'product', loadChildren: './module/product/product.module#ProductModule' }
// { path: 'product', loadChildren: 'src/app/module/product/product.module#ProductModule' }
{ path: 'product', loadChildren: () => import('./module/product/product.module').then(m => m.ProductModule) }
];
複製代碼
二、在自定義模塊中配置路由
const routes: Routes = [
{ path: '', component: UserComponent },
{ path: 'profile', component: ProfileComponent },
{ path: 'address', component: AddressComponent },
{ path: 'order', component: OrderComponent }
];
複製代碼
錯誤信息以下:
EXCEPTION: Uncaught (in promise): Error: Cannot find module 'app/home/home.module'
複製代碼
解決辦法:
const routes: Routes = [
// { path: 'user', loadChildren: './module/user/user.module#UserModule'},
// 更改路徑無效
// { path: 'user', loadChildren: 'src/app/module/user/user.module#UserModule'},
{ path: 'user', loadChildren: () => import('./module/user/user.module').then(m => m.UserModule) },
// { path: 'product', loadChildren: './module/product/product.module#ProductModule' }
// { path: 'product', loadChildren: 'src/app/module/product/product.module#ProductModule' }
{ path: 'product', loadChildren: () => import('./module/product/product.module').then(m => m.ProductModule) }
];
複製代碼