72 lines
2.2 KiB
Plaintext
72 lines
2.2 KiB
Plaintext
|
|
---
|
|||
|
|
title: 标题 Portal
|
|||
|
|
description: 将页面标题安全地挂载到应用外壳,同时保留 SSR fallback。
|
|||
|
|
order: 20
|
|||
|
|
toc:
|
|||
|
|
- id: info-resolver
|
|||
|
|
title: 页面信息解析器
|
|||
|
|
- id: managed-target
|
|||
|
|
title: 管理标题目标
|
|||
|
|
- id: fallback
|
|||
|
|
title: Fallback
|
|||
|
|
- id: nested-managers
|
|||
|
|
title: 嵌套 Manager
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 页面信息解析器 {#info-resolver}
|
|||
|
|
|
|||
|
|
`PagesManager.getPageInfo` 用于把路由或布局元数据接入页面组件。它接收 `PageContainer` 可选的 `Partial<PageInfo>`,返回补全后的 `PageInfo`;没有可用的托管信息时也可以返回 `undefined`:
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
<PagesManager
|
|||
|
|
getPageInfo={(info) => ({
|
|||
|
|
breadcrumb: info?.breadcrumb ?? routeMetadata.breadcrumb,
|
|||
|
|
description: info?.description ?? routeMetadata.description,
|
|||
|
|
subtitle: info?.subtitle ?? routeMetadata.subtitle,
|
|||
|
|
title: info?.title ?? routeMetadata.title,
|
|||
|
|
})}
|
|||
|
|
>
|
|||
|
|
<Outlet />
|
|||
|
|
</PagesManager>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
解析器返回 `undefined` 时,`PageContainer` 仍会把自身局部信息与继承的页面信息合并。
|
|||
|
|
|
|||
|
|
## 管理标题目标 {#managed-target}
|
|||
|
|
|
|||
|
|
布局可以把 DOM 容器交给 `PagesManager`,页面再通过 `PageTitlePortal` 把标题放进外部 Header:
|
|||
|
|
|
|||
|
|
```tsx
|
|||
|
|
function ApplicationLayout() {
|
|||
|
|
const [titleContainer, setTitleContainer] =
|
|||
|
|
React.useState<HTMLElement | null>(null)
|
|||
|
|
|
|||
|
|
return (
|
|||
|
|
<PagesManager titleContainer={titleContainer}>
|
|||
|
|
<header>
|
|||
|
|
<div ref={setTitleContainer} />
|
|||
|
|
</header>
|
|||
|
|
<Outlet />
|
|||
|
|
</PagesManager>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function ProductsPage() {
|
|||
|
|
return (
|
|||
|
|
<PageTitlePortal>
|
|||
|
|
<PageTitle>商品</PageTitle>
|
|||
|
|
</PageTitlePortal>
|
|||
|
|
)
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
`titleContainer` 接受 `Element` 或 `DocumentFragment`。`PageTitlePortal` 也可以通过自己的 `container` prop 覆盖 Manager。
|
|||
|
|
|
|||
|
|
## Fallback {#fallback}
|
|||
|
|
|
|||
|
|
没有可用目标时,Portal 默认原位渲染 `children`,因此服务端渲染和第一次客户端渲染不会丢失页面标题。传入 `fallback` 可以替换原位内容,包括传入 `null` 隐藏它。
|
|||
|
|
|
|||
|
|
## 嵌套 Manager {#nested-managers}
|
|||
|
|
|
|||
|
|
嵌套 `PagesManager` 在未传 `getPageInfo` 和 `titleContainer` 时会继承父级解析器与标题目标。显式传入 `null` 作为 `titleContainer` 可以阻止标题目标继承,使该子树中的标题继续原位渲染。
|