如何通过实践篇有效解决微前端single问题?

2026-05-25 14:011阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1029个文字,预计阅读时间需要5分钟。

如何通过实践篇有效解决微前端single问题?

介绍微前端+single-spa项目过程中,遇到的Vue子应用和React子应用路由跳转问题,及实际项目中的解决方案。

前言:本文主要介绍在微前端+single-spa项目过程中,遇到的Vue子应用和React子应用路由跳转问题,及实际项目中的解决方案。

介绍微前端 single-spa 项目过程中,遇到的 Vue 子应用和 React 子应用路由跳转问题,及实际项目中的解决方案。 前言

本文介绍的是在做微前端 single-spa 项目过程中,遇到的 Vue 子应用和 React 子应用互相跳转路由时遇到的问题。

项目情况:single-spa 项目,基座用的是 React,目前是2个子应用一个 Vue 一个 React。路由方案是 Vue Router,React Router + history。

有交互场景是从 Vue 子应用跳转到 React 子应用,或者从 React 子应用跳转到 Vue 子应用,因此遇到了问题。

遇到的问题

如何通过实践篇有效解决微前端single问题?

结合项目诉求和遇到的问题,大家可以先思考一下有什么解决方案~

------------------------------分割线------------------------------

解决的方案

主要是要处理好以下2个因素:

  • 正常触发当前页面的路由钩子
  • 正常传路由参数到目的页面
    我一开始尝试去查阅社区文章和看部分源码,看是否有什么特殊方式自主去触发路由钩子,等钩子处理完成之后再跳转去目的页面(跳去 Vue 用 Vue Router,跳去 React 用 React Router)

但看源码下来发现,想要触发 Prompt 还是需要调用 history.push 触发流程,想要触发 Vue Router 导航守卫还是需要调用 VueRouter.push 触发流程

所以结合这两点我整出了解决方案,已使用在项目当中,下面是封装的全局路由跳转工具:

window.micro = { // 子应用,会在相应应用挂载完成后设置 apps: { vue: null, react: null }, history: { push: (location, onComplete, onAbort) => { const url = typeof location === 'string' ? location : location.path; // 判断是哪个子应用 const currentIsReact = isReactApp(); const nextIsReact = isReactApp(`#${url}`); // 处理路由参数 let state = {}; let query = {}; let name = ''; if (typeof location !== 'string') { state = location.params || {}; query = location.query || {}; name = location.name || ''; } if (!currentIsReact && nextIsReact) { // vue 跳 react:先用 vue-router 跳,在跳完的回调里再用 history 跳 const reactHistoryHandle = () => { onComplete?.(); history.push(`#/temp?t=${Math.random()}`); history.replace({ state, pathname: url, search: setQueryStringArgs(query) }); // 因为跳多了1次 vue-router,所以 back 一下 window.micro.apps.vue2.$router.back(); }; window.micro.apps.vue.$router.push(name ? { name, params: state, query } : { path: url, query }, reactHistoryHandle, onAbort); } else if (currentIsReact && !nextIsReact) { // react 跳 vue:先用 history 跳临时路由,再用 vue-router 跳,要配合 history.listen 做处理 react2vue = () => { window.micro.apps.vue.$router.push(name ? { name, params: state, query } : { path: url, query }, onComplete, onAbort); }; history.push('/temp_react_to_vue'); } else if (currentIsReact && nextIsReact) { // react 跳 react:没有特殊,正常用 history 跳 } else { // vue 跳 vue:没有特殊,正常用 vue-router 跳 } }, }, };

配合的监听和工具函数:

// 处理 react 跳 vue的情况 let react2vue = null; history.listen((location, action) => { // 处理在临时路由的下一个路由,要返回上一个路由时,需要跳过临时路由 if (location.pathname === '/temp_react_to_vue' && action === 'POP') { history.goBack(); } else if (location.pathname === '/temp_react_to_vue') { // 在这里跳去真实的 vue-router 路由 react2vue?.(); react2vue = null; } }); // 工具函数 function isReactApp(hash = location.hash) { // 实际根据自己微服务项目的子应用情况判断 return hash === '' || hash === '#/' || ['#/list', '#/read/', '#/compose', '#/login'].some(router => hash.startsWith(router)) ; } // 把query参数变成query字符串,如 {a:1, b:2} 返回 ?a=1&b=2 function setQueryStringArgs(args) { let str = ''; args = args || {}; for (const [key, value] of Object.entries(args)) { str += `${key}=${encodeURIComponent(String(value))}`; } return str ? `?${str}` : ''; } 总结

这是我在实际项目中使用的方案,如有更优雅更好的方案,希望在评论区和我讨论~

收获 / 小彩蛋

因为之前已经对 Vue Router 原理和源码比较熟悉了,所以这次借着这个问题,主要是去了解了 React Router 的 Prompt 组件的实现,这里简单总结一下:

本文共计1029个文字,预计阅读时间需要5分钟。

如何通过实践篇有效解决微前端single问题?

介绍微前端+single-spa项目过程中,遇到的Vue子应用和React子应用路由跳转问题,及实际项目中的解决方案。

前言:本文主要介绍在微前端+single-spa项目过程中,遇到的Vue子应用和React子应用路由跳转问题,及实际项目中的解决方案。

介绍微前端 single-spa 项目过程中,遇到的 Vue 子应用和 React 子应用路由跳转问题,及实际项目中的解决方案。 前言

本文介绍的是在做微前端 single-spa 项目过程中,遇到的 Vue 子应用和 React 子应用互相跳转路由时遇到的问题。

项目情况:single-spa 项目,基座用的是 React,目前是2个子应用一个 Vue 一个 React。路由方案是 Vue Router,React Router + history。

有交互场景是从 Vue 子应用跳转到 React 子应用,或者从 React 子应用跳转到 Vue 子应用,因此遇到了问题。

遇到的问题

如何通过实践篇有效解决微前端single问题?

结合项目诉求和遇到的问题,大家可以先思考一下有什么解决方案~

------------------------------分割线------------------------------

解决的方案

主要是要处理好以下2个因素:

  • 正常触发当前页面的路由钩子
  • 正常传路由参数到目的页面
    我一开始尝试去查阅社区文章和看部分源码,看是否有什么特殊方式自主去触发路由钩子,等钩子处理完成之后再跳转去目的页面(跳去 Vue 用 Vue Router,跳去 React 用 React Router)

但看源码下来发现,想要触发 Prompt 还是需要调用 history.push 触发流程,想要触发 Vue Router 导航守卫还是需要调用 VueRouter.push 触发流程

所以结合这两点我整出了解决方案,已使用在项目当中,下面是封装的全局路由跳转工具:

window.micro = { // 子应用,会在相应应用挂载完成后设置 apps: { vue: null, react: null }, history: { push: (location, onComplete, onAbort) => { const url = typeof location === 'string' ? location : location.path; // 判断是哪个子应用 const currentIsReact = isReactApp(); const nextIsReact = isReactApp(`#${url}`); // 处理路由参数 let state = {}; let query = {}; let name = ''; if (typeof location !== 'string') { state = location.params || {}; query = location.query || {}; name = location.name || ''; } if (!currentIsReact && nextIsReact) { // vue 跳 react:先用 vue-router 跳,在跳完的回调里再用 history 跳 const reactHistoryHandle = () => { onComplete?.(); history.push(`#/temp?t=${Math.random()}`); history.replace({ state, pathname: url, search: setQueryStringArgs(query) }); // 因为跳多了1次 vue-router,所以 back 一下 window.micro.apps.vue2.$router.back(); }; window.micro.apps.vue.$router.push(name ? { name, params: state, query } : { path: url, query }, reactHistoryHandle, onAbort); } else if (currentIsReact && !nextIsReact) { // react 跳 vue:先用 history 跳临时路由,再用 vue-router 跳,要配合 history.listen 做处理 react2vue = () => { window.micro.apps.vue.$router.push(name ? { name, params: state, query } : { path: url, query }, onComplete, onAbort); }; history.push('/temp_react_to_vue'); } else if (currentIsReact && nextIsReact) { // react 跳 react:没有特殊,正常用 history 跳 } else { // vue 跳 vue:没有特殊,正常用 vue-router 跳 } }, }, };

配合的监听和工具函数:

// 处理 react 跳 vue的情况 let react2vue = null; history.listen((location, action) => { // 处理在临时路由的下一个路由,要返回上一个路由时,需要跳过临时路由 if (location.pathname === '/temp_react_to_vue' && action === 'POP') { history.goBack(); } else if (location.pathname === '/temp_react_to_vue') { // 在这里跳去真实的 vue-router 路由 react2vue?.(); react2vue = null; } }); // 工具函数 function isReactApp(hash = location.hash) { // 实际根据自己微服务项目的子应用情况判断 return hash === '' || hash === '#/' || ['#/list', '#/read/', '#/compose', '#/login'].some(router => hash.startsWith(router)) ; } // 把query参数变成query字符串,如 {a:1, b:2} 返回 ?a=1&b=2 function setQueryStringArgs(args) { let str = ''; args = args || {}; for (const [key, value] of Object.entries(args)) { str += `${key}=${encodeURIComponent(String(value))}`; } return str ? `?${str}` : ''; } 总结

这是我在实际项目中使用的方案,如有更优雅更好的方案,希望在评论区和我讨论~

收获 / 小彩蛋

因为之前已经对 Vue Router 原理和源码比较熟悉了,所以这次借着这个问题,主要是去了解了 React Router 的 Prompt 组件的实现,这里简单总结一下: