react/umi,浏览器tab设置
场景:umi3升级到umi4以后,浏览器tab本来是跟随路由变化而变化,升级后浏览器tab失效
1. @ant-design/pro-layout 默认内置了为 document.title 同步路由 name 的机制。
它里面在 layout/breadcrumb 渲染和路由切换时会自动执行 document.title = currentPage.name || ...
。 即使你不配 title,不写 useEffect
,也能自动切。
2. 升级4后换掉了引用的 pro-layout ,(无论是 ali定制、x-ops还是其他基于 ProLayout 的库)可能删掉了这个内置逻辑。
通常公司定制的 pro-layout,不会主动帮你同步 document.title,或者 title 的来源不是路由 name,而是单独一份配置、或你必须在页面级做 set。
3. umi4 的 router 和 layout 声明式路由变化很大,原来的路由 name/title 不能自动同步到 tab。
4. 新版不主动设置 document.title
,页面不变就是因为没人调用了那个 set。
解决: 路由配置只有name没有title,不变 。
layouts文件,添加根据 route 文件,当前路由切换修改浏览器tab
import { history, Outlet, useLocation } from 'umi';
import routes from '../../config/routes';const location = useLocation();// 根据路径查找路由配置
const findRouteByPath = (routes: any[], path: string) => {// 标准化路径,去除末尾的斜杠(除非是根路径)const normalizedPath = path.length > 1 ? path.replace(/\/+$/, '') : path;for (const route of routes) {// 标准化路由路径const normalizedRoutePath = route.path.length > 1 ? route.path.replace(/\/+$/, '') : route.path;// 完全匹配if (normalizedRoutePath === normalizedPath) {return route;}// 前缀匹配检查是否为子路由if (route.routes && normalizedPath.startsWith(normalizedRoutePath + '/')) {const found = findRouteByPath(route.routes, normalizedPath);if (found) {return found;}}// 递归搜索子路由if (route.routes) {const found = findRouteByPath(route.routes, normalizedPath);if (found) {return found;}}}return null;
};// 监听路由变化并更新页面标题useEffect(() => {const updateDocumentTitle = () => {const currentRoute = findRouteByPath(routes, location.pathname);if (currentRoute && currentRoute.name) {document.title = `${currentRoute.name} - ${settings.title}`;} else {document.title = settings.title;}};// 立即更新一次标题updateDocumentTitle();// 监听路由变化 重置错误状态并更新标题const unlisten = history.listen(() => {errorBoundaryRef.current?.resetError();updateDocumentTitle();});return () => {unlisten();};}, [location.pathname, routes]);