1、已经定义好的全部的路由配置,需要是这种格式的,可以再加上关于icon的内容.
const routerMap = [
{
path: '/home',
breadcrumbName: 'Home',
},
{
path: '/page1',
breadcrumbName: 'Page 1',
children: [
{
path: '/page1/page101',
breadcrumbName: 'Page 101',
children: [
{
path: '/page1/page101/page10101',
breadcrumbName: 'Page 10101',
}, {
path: '/page1/page101/page10102',
breadcrumbName: 'Page 10102',
}
]
}, {
path: '/page1/page102',
breadcrumbName: 'Page 102',
children: [
{
path: '/page1/page102/page10201',
breadcrumbName: 'Page 10201',
}, {
path: '/page1/page102/page10202',
breadcrumbName: 'Page 10202',
}
]
}
]
}
]
2、代码
import React, { Component } from 'react'
import { Breadcrumb } from 'antd'
import { Link } from 'react-router-dom'
//1、已经定义好的全部的路由配置,需要是这种格式的,可以再加上关于icon的内容
const routerMap = [
{
path: '/home',
breadcrumbName: 'Home',
},
{
path: '/page1',
breadcrumbName: 'Page 1',
children: [
{
path: '/page1/page101',
breadcrumbName: 'Page 101',
children: [
{
path: '/page1/page101/page10101',
breadcrumbName: 'Page 10101',
}, {
path: '/page1/page101/page10102',
breadcrumbName: 'Page 10102',
}
]
}, {
path: '/page1/page102',
breadcrumbName: 'Page 102',
children: [
{
path: '/page1/page102/page10201',
breadcrumbName: 'Page 10201',
}, {
path: '/page1/page102/page10202',
breadcrumbName: 'Page 10202',
}
]
}
]
}
]
export default class Bread extends Component {
state = {
breadCrumb: [],//Breadcrumb.Item项数组
}
componentDidMount() {
this.renderBreadcrumbItems()
}
//2、根据全部的路由配置和当前页面的路径筛选得到一个数组,这个数组是当前页面路径所对应的路由配置
/* 对路由配置的每一项path与currentPath进行判断:
先判断是否相等:
相等:把该项的配置添加进routes数组中,包括path、breadcrumbName。
不相等:再判断当前页面路径currentPath是否是以当前路径开头。
若是:证明currentPath在他的children中,把该项的路由配置添加进routes数组中,包括path、breadcrumbName、children的内容为递归调用函数,传入当前项的children为参数。
若不是:直接进行下一项。
得到的数组需要进行翻转
*/
getRoutesList = () => {
const currentPath = this.props.pathname;//当前页面的路径
const routes = [];//符合当前路径过程的路由配置数组
// 闭包
function fn(data) {
data.forEach(item => {
//先判相等 再判开头
if (item.path === currentPath) {
//相等
routes.push({ path: item.path, breadcrumbName: item.breadcrumbName })
} else {
if (currentPath.startsWith(item.path)) {
//不相等,但是是他的children
routes.push({ path: item.path, breadcrumbName: item.breadcrumbName, children: fn(item.children) })
}
}
})
}
fn(routerMap)
return routes.reverse() //注意:这里要进行数组翻转
}
//3、根据筛选后的路由配置渲染Breadcrumb.Item:如果是最后一项则直接渲染文字文字内容,不是最后一项要渲染链接。
renderBreadcrumbItems = () => {
const routes = this.getRoutesList()
const currentPath = this.props.pathname
let breadCrumb = []
const bread = (data) => {
data.forEach(item => {
const { path, breadcrumbName, children } = item;
//判断是否是最后一项
const isLast = path === currentPath //true最后一项渲染文字,false渲染链接
const i = <Breadcrumb.Item key={path}>
{isLast ? <span>{breadcrumbName}</span> : <Link to={path}>{breadcrumbName}</Link>}
</Breadcrumb.Item>
breadCrumb.push(i)
if (children) {
bread(children)
}
})
}
bread(routes)
this.setState({
breadCrumb
})
}
render() {
return (
<div>
<Breadcrumb>
{this.state.breadCrumb}
</Breadcrumb>
</div>
)
}
}
3、在组件中使用的时候需要传入当前页面的路劲发作为Bread组件的属性。
<Bread pathname={this.props.location.pathname}></Bread>
4、假设当前页面的路径为 ‘/page1/page102/page10201’,经过上述操作筛选后得到的对应路径上的路由配置routes的值为:
routs=[
{path: '/page1', breadcrumbName: 'Page 1', children: undefined},
{path: '/page1/page102', breadcrumbName: 'Page 102', children: undefined},
{path: '/page1/page102/page10201', breadcrumbName: 'Page 10201'}
]
5、关于startWith:
startsWith 是 JavaScript 中一个字符串方法,用于检测一个字符串是否以指定的子串开头。如果是,则返回 true;如果不是,则返回 false。
这个方法对于构建面包屑导航或任何需要判断路径是否以特定前缀开始的场景都非常有用。
const str = 'Hello, world!';
const prefix = 'Hello';
if (str.startsWith(prefix)) {
console.log('The string starts with "Hello".');
} else {
console.log('The string does not start with "Hello".');
}
// 输出:The string starts with "Hello".
在路由匹配的上下文中,startsWith 可以用来检查当前路径是否以某个路由的路径开始。如果是这样,那么就可以认为该路由是当前路径的一个匹配项,并可能将其添加到面包屑导航中。
例如,如果你有一个路由对象,其 path 属性为 /home/profile,并且当前路径是 /home/profile/settings,那么调用 currentPath.startsWith(route.path) 将返回 true,因为当前路径确实以路由的路径开始。