说说我这两天开发时遇到的问题:如何在 antd pro v4 中把面包屑变为链接。
这个问题在 antd 的 issue 中可以找到相关提问及解决方案,然而对我来说没用呀!为什么?
面包屑由 PageHeaderWrapper 实现,Layout 将 根据 MenuData 生成的 breadcrumb,并通过 PageHeaderWrapper 将其展现。 PageHeaderWrapper 封装至 Ant Design 的 PageHeader,api 完全相同。
这是官方文档的描述,即如果要用内置的面包屑,则需要用到 PageHeaderWrapper 组件:
<PageHeaderWrapper
loading={loading}
>
<Card bordered={false}>
...
<Button onClick={this.cancelRelate} className={styles.cancelRelateBtn} loading={cancelRelateLoading}>
xxx
</Button>
<a href="#" onClick={this.checkRelateRule}>
xxx
</a>
<Table
{...tableProps}
/>
</Card>
</PageHeaderWrapper>
这样子的确可以正常展示出面包屑,可是面包屑只是文字而已,并不能点击。
而上述提到的 issue 提供的解决办法是修改 src/components/PageHeaderWrapper/breadcrumb.js 里的代码,可是现在 PageHeaderWrapper 组件已经被封装在依赖包 @ant-design/pro-layout 里的,换言之就算我去找到代码并且改了,那也是徒劳。
我根据文档说的,找到了页面这边的设置:
接着我在 layouts/BasicLayout.tsx 文件中发现了有关于面包屑的一些设置:
-
如果我把白色框这段代码注释掉,面包屑依旧可以展示;
-
如果我把橙色框的这段代码注释掉,则面包屑不会展示“首页”。
说明即使 PageHeaderWrapper 组件内置了面包屑,也是可以在这个文件中进行修改的。
最后通过翻 ProLayoutComponents 组件的源代码,我找到了解决方案:
itemRender={(router = {}) => {
if (router.component) {
return <Link to={router.path}>{router.breadcrumbName}</Link>
}
return router.breadcrumbName
}}
也就是下图白色框部分的内容:
OK~ 问题解决~~
但是产品还有另一个需求,某些页面的面包屑需要带上父查询条件,而且跳转到父页面后,查询条件需要回填到页面的过滤表单里,并且按照查询条件查询出页面数据。这个我实现起来有点儿挫,就不详细写了,大概思路说一下就好,如果各位看官有更优雅的实现方式,麻烦留言,我一定去做优化!
我在页面使用 PageHeaderWrapper 时,添加了 pageHeaderRender 属性:
<PageHeaderWrapper loading={loading} pageHeaderRender={(routers) => this.pageHeaderRender(routers)} >
通过编写 this.pageHeaderRender 返回一个数组数据。
pageHeaderRender 必须要返回一个数组,而且数组项不能是对象,这也是我疑惑的地方,明明文档说了
PageHeaderWrapper 封装至 Ant Design 的 PageHeader,api 完全相同。
而 PageHeader 的属性难道不应该是一个对象?
最后我的处理结果是返回一个数组,数组项是一个个 html,就像是这样子:
[
<Fragment>
<span className={styles.breadcrumbSpan}>{xxx}</span><span className={styles.breadcrumbSlash}>/</span>
</Fragment>,
<Fragment>
<Link to={path} className={styles.breadcrumbLink}>{xxx}</Link><span className={styles.breadcrumbSlash}>/</span>
</Fragment>,
<Fragment>
<a
className={styles.breadcrumbLink}
href="#"
onClick={(e) => {
e.preventDefault()
const { dispatch } = this.props
dispatch(routerRedux.push({
pathname: path,
query: {
filterValues,
}
}))
}}
>
{breadcrumbName}
</a>
</Fragment>
]
很挫,但是可以用 :)