一、前期準(zhǔn)備
- 面包屑組件(最好能封裝成共享組件)
- 一些路由信息配置
- Ant-Zorro 組件的環(huán)境配置(這里會(huì)套用里面的一些現(xiàn)成的組件庫),版本: 7.0.1
二、Ant-Zorro 配置
這里請參考官方網(wǎng)站 https://ng.ant.design/docs/getting-started/zh 泡孩,官方網(wǎng)站中,找到目錄 快速上手 寺谤,在里面有 自行構(gòu)建仑鸥,查看 自行構(gòu)建 下的內(nèi)容。
如果依然不能成功变屁,可以瀏覽參考博主的另一個(gè)博客:
里面講了一些博主在配置 Ant-Zorro 的時(shí)候遇到的坑眼俊!
三、自定義面包屑組件
1. 創(chuàng)建一個(gè)自己的面包屑組件
ng g c breadcrumb --spec=false
2. 使用 Ant-Zorro 的面包屑組件
<nz-breadcrumb>
<nz-breadcrumb-item>Home</nz-breadcrumb-item>
<nz-breadcrumb-item><a>Application List</a></nz-breadcrumb-item>
<nz-breadcrumb-item>An Application</nz-breadcrumb-item>
</nz-breadcrumb>
將 Ant-Zorro 組件庫中的面包屑組件粟关,放到自己創(chuàng)建的面包屑組件的html文件中疮胖。將組件庫中的面包屑做一點(diǎn)改動(dòng),將靜態(tài)的面包屑改成動(dòng)態(tài)的闷板,使用 ngFor 循環(huán)自行加載澎灸,對應(yīng)的路由信息。
<nz-breadcrumb>
<nz-breadcrumb-item>首頁</nz-breadcrumb-item>
<nz-breadcrumb-item *ngFor="let breadcrumb of breadcrumbs">
<a [routerLink]="[breadcrumb.url, breadcrumb.params]">{{ breadcrumb.label }}</a>
</nz-breadcrumb-item>
</nz-breadcrumb>
3. 面包屑邏輯代碼
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, NavigationEnd, Params, PRIMARY_OUTLET } from '@angular/router';
import { filter } from 'rxjs/operators';
interface IBreadcrumb {
label: string;
params: Params;
url: string;
}
@Component({
selector: 'app-breadcrumb',
templateUrl: './breadcrumb.component.html',
styleUrls: ['./breadcrumb.component.scss']
})
export class BreadcrumbComponent implements OnInit {
public breadcrumbs: IBreadcrumb[];
constructor(
private activatedRoute: ActivatedRoute,
private router: Router
) {
this.breadcrumbs = [];
}
ngOnInit() {
// 訂閱NavigationEnd事件
this.router.events.pipe(filter(event => event instanceof NavigationEnd))
.subscribe(event => {
// 設(shè)置面包屑
const root: ActivatedRoute = this.activatedRoute.root;
console.log('=== janine.樹的的根路由', root);
this.breadcrumbs = this.getBreadcrumbs(root);
});
}
/**
* 返回表示面包屑的IBreadcrumb對象的數(shù)組
*/
private getBreadcrumbs(route: ActivatedRoute, url: string = '', breadcrumbs: IBreadcrumb[] = []): IBreadcrumb[] {
const ROUTE_DATA_BREADCRUMB = 'breadcrumb';
// 得到子路由
const children: ActivatedRoute[] = route.children;
console.log('=== janine.有多少子路由 ===', children);
// 如果沒有子路由返回
if (children.length === 0) {
console.log('=== janine.沒有子路由是 ===', breadcrumbs);
return breadcrumbs;
}
// 遍歷每個(gè)子元素
for (const child of children) {
// 驗(yàn)證主路由
if (child.outlet !== PRIMARY_OUTLET) {
continue;
}
// 驗(yàn)證路由上指定的自定義數(shù)據(jù)屬性'breadcrumb'
if (!child.snapshot.data.hasOwnProperty(ROUTE_DATA_BREADCRUMB)) {
return this.getBreadcrumbs(child, url, breadcrumbs);
}
// 獲取路由的URL進(jìn)行分割
const routeURL: string = child.snapshot.url.map(segment => segment.path).join('/');
// append route URL to URL 追加路由的url到url
if (routeURL) {
console.log('=== janine.routeURL ===', routeURL);
url += `/${routeURL}`;
}
// 添加面包屑
const breadcrumb: IBreadcrumb = {
label: child.snapshot.data[ROUTE_DATA_BREADCRUMB],
params: child.snapshot.params,
url: url
};
// 此處的 component 如果為 undefined遮晚,可能是因?yàn)閼屑虞d性昭,在查找時(shí),沒有找到 component 的值鹏漆,
// 所以當(dāng) component 為 undefined 的時(shí)候,就會(huì)又往數(shù)組里再追加一次创泄,會(huì)重復(fù)
if (child.component) {
breadcrumbs.push(breadcrumb);
}
console.log('=== janine.breadcrumbs === ', breadcrumb);
// 遞歸
return this.getBreadcrumbs(child, url, breadcrumbs);
}
}
}
4. 知識(shí)點(diǎn)
(1) filter
import { filter } from 'rxjs/operators';
rxjs 的 filter() 方法艺玲,是 Angular6的,不是其他版本鞠抑,如果版本不對饭聚,會(huì)出錯(cuò)! 對應(yīng)的使用步驟如下:
ngOnInit() {
// 訂閱NavigationEnd事件
this.router.events.pipe(filter(event => event instanceof NavigationEnd))
.subscribe(event => {
// 設(shè)置面包屑
const root: ActivatedRoute = this.activatedRoute.root;
console.log('=== janine.樹的的根路由', root);
this.breadcrumbs = this.getBreadcrumbs(root);
});
}
(2)NavigationEnd, Params, PRIMARY_OUTLET
Router 和 ActivatedRoute 就不說了,這是 Angular 路由最常見的搁拙。講一下 NavigationEnd, Params, PRIMARY_OUTLET秒梳。
- NavigationEnd:表示當(dāng)導(dǎo)航 成功結(jié)束 時(shí)(當(dāng)從一個(gè)路徑到另一個(gè)導(dǎo)航已經(jīng)完成時(shí))觸發(fā)的事件法绵。
- Params:用來設(shè)置 IBreadcrumb 接口的 params 的類型為 Params。params 為非必需酪碘,其他兩個(gè)為必需的朋譬。
interface IBreadcrumb {
label: string;
params: Params;
url: string;
}
- PRIMARY_OUTLET:一個(gè)常量 primary
(3) 添加面包屑
代碼中,有一段是將路由追加到數(shù)組中兴垦。這里會(huì)有一個(gè)關(guān)于懶加載的問題徙赢,代碼注釋里已經(jīng)說明了。
如果有懶加載就得加個(gè)判讀 child.component 是否 為 undefined 探越,只有不是 undefined 時(shí)才能向數(shù)組中追加狡赐,否則會(huì)重復(fù)(這里可以去掉判斷,自己 debugger 一下钦幔,關(guān)注一下 component 值的變化枕屉,和數(shù)組追加后數(shù)組值的變化情況)。
如果沒有懶加載鲤氢,可以不對 breadcrumbs.push(breadcrumb); 做判斷搀擂!
// 添加面包屑
const breadcrumb: IBreadcrumb = {
label: child.snapshot.data[ROUTE_DATA_BREADCRUMB],
params: child.snapshot.params,
url: url
};
// 此處的 component 如果為 undefined,可能是因?yàn)閼屑虞d铜异,在查找時(shí)哥倔,沒有找到 component 的值,
// 所以當(dāng) component 為 undefined 的時(shí)候揍庄,就會(huì)又往數(shù)組里再追加一次咆蒿,會(huì)重復(fù)
if (child.component) {
breadcrumbs.push(breadcrumb);
}
5. 路由信息配置: data: { breadcrumb: 'xxx' }
export const routes = [
{
// 路由為空時(shí),自動(dòng)重定向到/home
path: '',
redirectTo: '/home/basic',
pathMatch: 'full',
},
{
path: 'home', component: HomeComponent,
children: [
{
path: 'basic', loadChildren: './basic/basic.module#BasicModule',
data: { breadcrumb: '基礎(chǔ)' }
},
...
{
path: 'server', loadChildren: './server/server.module#ServerModule',
data: { breadcrumb: '服務(wù)' }
}
]
},
];
如果模塊中蚂子,還有子路由沃测,也是同樣配置!
6. 效果圖:
附錄
源碼地址:https://github.com/Janine-ZN/ng-basic (重點(diǎn):breadcrumb.component.ts 和 routes.ts,還有一些模塊中的路由配置)
參考的博客是針對 Angular2 的食茎,而且不適用于路由懶加載蒂破,如果有路由懶加載的地方頁面可能會(huì)出重復(fù)的路由。
博客參考地址:
https://yfblog.cn/angular2-breadcrumb-using-router.html
關(guān)注博主公眾號别渔,更多精彩等著你8矫浴!哎媚!