背景:项目使用qiankun微前端开发,同一个侧边栏中有多个菜单,菜单对应页面来自于不同子项目,产品需要新建任务时点击其他页面需要弹窗拦截二次确认后再退出,但由于qinakun的机制是提供路由变化自动更换子项目,导致点击新的子服务时会直接将当前服务注销掉,就无法触发路由守卫,而基座无法触发子服务路由守卫。 ## \*\*概述\*\* URL 拦截器是一个用于拦截页面导航行为的工具类,可以在页面跳转前进行拦截处理。支持拦截 \`history.pushState\`、\`history.replaceState\`、\`window.open\`、\`history.go\`、\`history.back\` 等浏览器导航方法。 ## \*\*原理\*\* 该拦截器通过重写浏览器原生的导航方法来实现拦截功能: 1. \*\*方法重写\*\*:在初始化时保存原始的浏览器方法,然后用自定义方法替换 2. \*\*拦截检查\*\*:在每次导航操作前,根据配置的规则检查是否需要拦截 3. \*\*回调处理\*\*:如果需要拦截,调用用户提供的回调函数进行处理 4. \*\*条件执行\*\*:根据回调函数的返回值决定是否继续执行原始的导航操作 ## \*\*安装使用\*\* \`\`\`plain import { FConfirm, FUtils } from 'skynet-pandora-ui' const { urlInterceptor } = FUtils onMounted(() =\> { urlInterceptor?.init( { mode: 'allow', routes: \[\] }, (_info: any, resolve: any) =\> { resolve() } ) }) onBeforeUnmount(() =\> { urlInterceptor?.destroy() }) \`\`\` ## \*\*基本用法\*\* ### \*\*1. 基础配置\*\* \`\`\`plain // 阻止模式:阻止访问指定路由 const blockConfig: InterceptConfig = { mode: 'block', routes: \['/admin', '/settings'\], message: '无权限访问此页面', redirectTo: '/login' } // 允许模式:只允许访问指定路由 const allowConfig: InterceptConfig = { mode: 'allow', routes: \['/home', '/profile', '/dashboard'\], message: '当前页面不可访问' } \`\`\` \*\*拦截模式说明\*\* \*\*Block 模式\*\* - \*\*作用\*\*:阻止访问指定的路由 - \*\*逻辑\*\*:当 URL 包含配置的路由时进行拦截 - \*\*适用场景\*\*:权限控制、敏感页面保护 \*\*Allow 模式\*\* - \*\*作用\*\*:只允许访问指定的路由 - \*\*逻辑\*\*:当 URL 不包含配置的路由时进行拦截 - \*\*适用场景\*\*:白名单控制、受限环境 ### \*\*2. 初始化拦截器\*\* \`\`\`plain urlInterceptor.init(blockConfig, (info: NavigationInfo, resolve: (allow: boolean) =\> void) =\> { // 自定义拦截逻辑 console.log('导航信息:', info) // 可以在这里添加确认对话框、权限检查等逻辑 const userConfirmed = confirm(\`确定要访问 ${info.url} 吗?\`) // 调用 resolve 函数决定是否允许导航 resolve() }) \`\`\` ### \*\*3. 销毁拦截器\*\* \`\`\`plain // 恢复原始的浏览器方法 urlInterceptor.destroy() \`\`\` ## \*\*注意事项\*\* 1. \*\*浏览器环境检查\*\*:拦截器会自动检查是否在浏览器环境中运行 2. \*\*单例模式\*\*:全局只能有一个拦截器实例 3. \*\*配置覆盖\*\*:重复调用 \`init\` 方法会覆盖之前的配置 4. \*\*方法恢复\*\*:使用完毕后建议调用 \`destroy\` 方法恢复原始浏览器方法 5. \*\*路由匹配\*\*:当前使用 \`includes\` 方法进行字符串包含匹配,支持部分路径匹配 ## \*\*支持的\*\*\*\*导航\*\*\*\*类型\*\* + \`pushState\`: history.pushState 方法 + \`replaceState\`: history.replaceState 方法 + \`open\`: window.open 方法 + \`go\`: history.go 方法 + \`back\`: history.back 方法 ## 完整代码