umi 3 实现路由拦截

关于umi3 如何实现路由拦截
umi 版本

"umi": "^3.2.20",

umi 内置了history 基于 React router 封装的路由历史管理工具,核心用于控制路由的跳转,监听路由的变化
核型作用

  • 管理路由状态,记录页面访问轨迹。
  • 提供编程式路由操作 API,无需手动编写链接或表单提交。
  • 适配 umi 不同路由模式(hash、browser、memory)的统一调用方式

主要使用方式

  • 通过 useHistory 钩子(函数组件) 函数组件中使用 hooks 获取 history 实例避免全局导入的耦合
  • 类组件通过withRouter 高阶组件 为类组件注入 history、location、match 等路由相关属性。

核心 API
push (path, state):跳转到指定路径,新增历史记录。
replace (path, state):替换当前历史记录,跳转后无法回退到上一页。
go (n):前进或后退 n 步(n 为正数前进,负数后退)。
goBack ():等价于 go (-1),回退上一页。
goForward ():等价于 go (1),前进下一页。
listen (callback):监听路由变化,回调参数包含 location 和 action 信息。
umi3 的 history 和原生的区别
在这里插入图片描述

window.history.pushState() 有三个参数,每个参数的属性和特性如下:

  1. 第一个参数:stateObject(状态对象)
    类型:普通对象(或 null),会被序列化存储。
    核心属性:
    与新添加的历史记录绑定,可通过 history.state 直接访问当前历史记录的状态对象。
    当触发 popstate 事件时(如用户点击前进 / 后退按钮),事件对象的 state 属性会指向该对象。
    限制:
    大小限制:不同浏览器对状态对象的存储大小有限制(通常约 640KB),超出会抛出错误。
    序列化要求:内部会通过结构化克隆算法(Structured Cloning Algorithm)序列化,因此不能包含函数、循环引用、Symbol 等无法序列化的数据,否则会报错。
    用途:通常存储与当前 URL 相关的状态数据(如路由参数、页面状态),用于页面回退 / 前进时恢复页面内容。
  2. 第二个参数:title(标题)
    类型:字符串(或 null)。
    核心属性:
    理论上表示新历史记录对应的页面标题,但目前所有主流浏览器(Chrome、Firefox、Safari 等)均忽略此参数,不会更新页面标题。
    用途:由于浏览器不处理,实际使用中通常传空字符串 “” 或 null,未来若浏览器支持,可能用于设置标题。
  3. 第三个参数:url(URL 地址)
    类型:字符串(可选,不传则默认使用当前 URL)。
    核心属性:
    会显示在浏览器地址栏,修改当前页面的 URL,但不会触发页面刷新或向服务器发送请求。
    必须与当前页面同源(协议、域名、端口完全一致),否则会抛出 SecurityError 异常。
    可以是相对路径(如 “./page2”、“/user”)或绝对路径(如 “https://example.com/page2”)。
    若 URL 包含哈希(如 “/page#section1”),仅会更新哈希部分,不影响历史记录的其他部分。
    用途:用于修改 URL 以匹配当前页面的逻辑状态(如单页应用的路由路径),让用户感知到 URL 变化,同时支持通过 URL 直接访问对应页面。
    总结
    三个参数的核心作用:
    stateObject:存储状态数据,用于页面回退 / 前进时恢复状态。
    title:预留参数,目前无实际作用。
    url:修改浏览器地址栏 URL,实现无刷新的 URL 更新。
    例如:
    javascript
    运行
    history.pushState(
    { id: 1, type: ‘article’ }, // 状态对象(存储页面相关数据)
    ‘’, // 标题(忽略)
    ‘/articles/1’ // 新URL(显示在地址栏)
    );
    在 React Router 中,history.listen((location, action) => { … }) 回调函数的两个参数 location 和 action 具有明确的类型定义,以下是具体说明(基于 TypeScript 类型):
  4. location 参数
    类型为 Location(React Router 定义的接口),包含当前路由的位置信息,核心属性如下:
    typescript
    interface Location<State = any> {
    pathname: string; // URL 路径部分(如 “/user/123”)
    search: string; // URL 查询字符串(如 “?name=foo&age=20”)
    hash: string; // URL 哈希部分(如 “#section1”)
    state: State | undefined; // 路由状态(由 pushState/replaceState 传入的 state 对象)
    key: string; // 唯一标识当前位置的键(如 “l24mu”)
    }
    pathname:字符串,当前 URL 的路径部分,始终以 / 开头。
    search:字符串,查询参数部分,包含 ? 前缀(若没有查询参数则为空字符串)。
    hash:字符串,哈希部分,包含 # 前缀(若没有哈希则为空字符串)。
    state:任意类型,对应 history.pushState 传入的 stateObject,默认 undefined。
    key:字符串,React Router 自动生成的唯一键,用于区分不同的历史记录。
  5. action 参数
    类型为 HistoryAction(字符串字面量类型),表示触发路由变化的动作,可能的值为:
    typescript
    type HistoryAction = “POP” | “PUSH” | “REPLACE”;
    “PUSH”:通过 history.push() 新增历史记录(如点击 或调用 push 方法)。
    “REPLACE”:通过 history.replace() 替换当前历史记录(如调用 replace 方法)。
    “POP”:通过浏览器前进 / 后退按钮或 history.go()/back()/forward() 触发的历史记录切换。
    示例(TypeScript)
    typescript
    import { History, Location } from “history”;

const history: History = …; // 从 React Router 中获取的 history 对象

history.listen((location: Location, action: “POP” | “PUSH” | “REPLACE”) => {
console.log(“路径:”, location.pathname);
console.log(“查询参数:”, location.search);
console.log(“动作:”, action); // “POP” | “PUSH” | “REPLACE”
});
总结
location 是包含路由路径、参数、状态等信息的对象,类型为 Location。
action 是表示路由变化类型的字符串,只能是 “POP”、“PUSH”、“REPLACE” 三者之一。

<think> 在 Umi 中,获取当前路由地址的方法主要有以下几种(基于 Umi 的运行时 API): ### 1. 使用 `useLocation` 钩子(函数组件) ```jsx import { useLocation } from &#39;umi&#39;; function MyComponent() { const location = useLocation(); // 完整路径(包含查询参数) console.log(location.pathname + location.search); // 仅路径部分 console.log(location.pathname); // 例如:&#39;/users/123&#39; return <div>当前路由:{location.pathname}</div>; } ``` ### 2. 使用 `withRouter` 高阶组件(类组件) ```jsx import { withRouter } from &#39;umi&#39;; class MyComponent extends React.Component { render() { const { location } = this.props; return <div>当前路由:{location.pathname}</div>; } } export default withRouter(MyComponent); ``` ### 3. 使用 Umi 的 `history` 对象(任何地方) ```javascript // 在组件外(如工具函数、请求拦截器中) import { history } from &#39;umi&#39;; // 获取当前路由信息(注意:history.location 是可变对象,需即时使用) const currentPath = history.location.pathname; ``` ### 4. 在页面组件中通过 `props` 获取(Umi 页面级组件) Umi 会自动向页面组件(`src/pages` 下的组件)注入路由属性: ```jsx export default function Page(props) { // 通过 props.location 获取 return <div>当前路由:{props.location.pathname}</div>; } ``` ### 5. 获取路由参数(动态路由) ```jsx import { useParams } from &#39;umi&#39;; function UserPage() { // 假设路由为 /users/:id const params = useParams(); console.log(params.id); // 输出动态路由参数 } ``` ### 6. 获取查询参数(URL 参数) ```jsx import { useLocation } from &#39;umi&#39;; function SearchPage() { const location = useLocation(); const query = new URLSearchParams(location.search); const keyword = query.get(&#39;q&#39;); // 例如:?q=umi → "umi" } ``` ### 特殊场景:在 Umi 插件中获取 ```javascript export function patchRoutes({ routes, route }) { // 通过 route 对象获取当前匹配的路由信息(服务端/插件端) console.log(route.path); } ``` ### ⚠️ 注意事项 1. **`history.location` 的时效性**: 直接使用 `history.location` 时,因 Umi 的 `history` 是单例对象,其 `location` 会随路由变化而更新。但在异步回调中获取可能是最新值,建议用 `history.listen` 监听变化: ```javascript import { history } from &#39;umi&#39;; history.listen(({ location }) => { console.log(&#39;路由变化:&#39;, location.pathname); }); ``` 2. **Umi 版本兼容性**: 以上方法适用于 Umi 3Umi 4(基于 React Router v5/v6 适配)。 3. **路由信息结构**: `location` 对象包含: ```typescript { pathname: &#39;/users/123&#39;, // 路径 search: &#39;?name=umi&#39;, // 查询字符串 hash: &#39;#section&#39;, // hash state: { from: &#39;/&#39; }, // 路由跳转时传递的 state } ``` ### 总结表格 | **场景** | **推荐方法** | **示例代码片段** | |------------------------------|----------------------------------|------------------------------------------| | 函数组件中获取路径 | `useLocation` | `const { pathname } = useLocation();` | | 类组件中获取路径 | `withRouter` | `withRouter(MyComponent)` | | 非组件环境(工具函数) | `history.location` | `import { history } from &#39;umi&#39;;` | | 监听路由变化 | `history.listen` | `history.listen(location => {...})` | | 获取动态路由参数 | `useParams` | `const params = useParams();` | | 获取 URL 查询参数 | `URLSearchParams` | `new URLSearchParams(location.search)` | §§相关问题§§ 1. Umi 中如何监听路由变化并执行异步操作? 2. 在 Umi 插件中如何修改当前路由配置? 3. Umi 4 的路由配置与 v3 有哪些主要区别? 4. 如何从路由配置文件中获取当前页面的路由信息? </think>在 Umi.js 框架中获取当前路由地址,可以通过以下几种方法实现(适用于 Umi 3/4 版本): ### 方法一:使用 Umi 的 `useLocation` 钩子(推荐) ```jsx import { useLocation } from &#39;umi&#39;; function YourComponent() { const location = useLocation(); // 获取完整路由路径(包含查询参数) const fullPath = location.pathname + location.search; // 仅获取路径部分 const currentRoute = location.pathname; // 例如:/users/profile return ( <div> 当前路由: {currentRoute} <br /> 完整路径: {fullPath} </div> ); } ``` ### 方法二:通过页面 props 获取(适用于页面组件) ```jsx export default function Page(props) { // Umi 自动向页面组件注入路由信息 const currentRoute = props.location.pathname; return <div>当前路由:{currentRoute}</div>; } ``` ### 方法三:使用 `history` 对象(全局获取) ```javascript // 在任何文件中(包括非组件文件) import { history } from &#39;umi&#39;; // 获取当前路由路径 const currentPath = history.location.pathname; // 监听路由变化 history.listen(({ pathname }) => { console.log(&#39;路由变化:&#39;, pathname); }); ``` ### 方法四:获取动态路由参数 ```jsx import { useParams } from &#39;umi&#39;; // 假设路由配置为 /users/:id function UserPage() { const params = useParams(); const userId = params.id; // 获取动态参数 return <div>用户ID: {userId}</div>; } ``` ### 方法五:获取查询参数(URL 参数) ```jsx import { useLocation } from &#39;umi&#39;; function SearchPage() { const location = useLocation(); const query = new URLSearchParams(location.search); // 获取 ?name=umi 中的 name 值 const name = query.get(&#39;name&#39;); return <div>搜索关键词: {name}</div>; } ``` ### ⚠️ 注意事项 1. **路由配置**:确保在 `.umirc.ts` 或 `config/config.ts` 中已配置路由 ```ts // .umirc.ts export default { routes: [ { path: &#39;/&#39;, component: &#39;index&#39; }, { path: &#39;/users/:id&#39;, component: &#39;user&#39; } ] } ``` 2. **路由监听**:使用 `history.listen` 监听路由变化时,记得在组件卸载时取消监听 ```jsx useEffect(() => { const unlisten = history.listen((location) => { console.log(&#39;Route changed:&#39;, location.pathname); }); return () => unlisten(); // 清理监听器 }, []); ``` ### 方法对比表 | **使用场景** | **推荐方法** | **是否支持动态参数** | **是否支持 SSR** | |----------------------|--------------------|----------------------|------------------| | 函数组件 | `useLocation` | ✅ | ✅ | | 页面组件 | `props.location` | ✅ | ✅ | | 非组件环境 | `history.location` | ✅ | ❌ | | 获取查询参数 | `URLSearchParams` | ❌ | ✅ | | 监听路由变化 | `history.listen` | ✅ | ❌ | > 提示:在 Umi 4 中,路由系统基于 React Router v6,上述 API 与 React Router 保持一致[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值