相互跳转
(1)主应用跳转子应用
主应用跳转子应用直接使用router的push即可。
router.push('/vueSub');
跳转过去后我们发现主页面就被替换了,如果需要返回,点击浏览器左上角的返回按钮就能返回,但是如果需要在界面中点击一个按钮返回,则无法使用router.push('/') ,因为这里的router是子应用自己的router实例,无法识别的主应用中的路径,如果要返回主应用,在官方解答中提到两个方法
- 主应用和微应用都是 hash 模式,主应用根据 hash 来判断微应用,则不用考虑这个问题。
- 主应用根据 path 来判断微应用history 模式的微应用之间的跳转,或者微应用跳主应用页面,直接使用微应用的路由实例是不行的,原因是微应用的路由实例跳转都基于路由的 base。有两种办法可以跳转:
-
- history.pushState():mdn 用法介绍
- 将主应用的路由实例通过 props 传给微应用,微应用这个路由实例跳转。
这里我是使用的第二种方法,将主应用的router实例传过来。
(2)子应用返回主应用(重点)
在主应用中注册子应用的时候,我已经将主应用的router实例通过props传了过来,如下图。
接收主应用的router
在子应用的main.js配置中,生命周期的方法里,可以获取到前面注册传入的props参数
所以可以在render方法中,获取到主应用的router实例,并且放到子应用的vue全局属性中。
首先获取router,通过props.router就可以获取到主应用的实例
在vue2.0中可以通过 Vue. prototype.xxx = props.router来获取,调用使用this.xxx就能得到。
但是在vue3.0 中需要使用config.globalProperties代替prototype, 具体如下代码
function render(props = {}) {
const { container } = props;
instance = createApp(App);
instance.use(store)
.use(router)
.use(Antd)
.mount(container ? container.querySelector('#app') : '#app');
instance.config.globalProperties.mainRouter = props.router;
console.log('主应用router', props.router);
}
获取到主应用的router实例后,我们需要在后面的页面中使用到他。这里有个小知识点
getCurrentInstance代表上下文,即当前实例。ctx相当于Vue2的this, 但是需要特别注意的是ctx代替this只适用于开发阶段,如果将项目打包放到生产服务器上运行,就会出错,ctx无法获取路由和全局挂载对象的。此问题的解决方案就是使用proxy替代ctx,代码参考如下。
<script>
import { defineComponent, getCurrentInstance } from 'vue'
export default defineComponent({
name: '',
setup(){
const { proxy } = getCurrentInstance() // 使用proxy代替ctx,因为ctx只在开发环境有效
console.log(proxy.$root.$route, proxy.$root.$router) // 路由信息
console.log(proxy.$systemName) // 全局挂载对象
return {
}
}
})
</script>
所以我们在这里就使用proxy来获取主应用 的router实例, 然后在方法中调用push方法即可返回主应用。
....
setup() {
//主应用路由获取,不能放到backMain方法中,必须放在外面
const { proxy } = getCurrentInstance();
const mainRouter = proxy.mainRouter;
const backMain = () => {
//通过主路由返回到主应用
mainRouter.push('/');
};
const logout = () => {};
return {
backMain,
};
},
};
...
获取主应用的router还有一种方法是通过vue里的provide,inject来传递。
//主应用 rander方法中设置
instance.provide('maiAppRouter', props.router);
//子应用
const mainAppRouter = inject('maiAppRouter');
mainAppRouter.push('/')
\