微前端架构下,主利用有本人的路由模块,同时主利用反对以微前端的形式嵌入业务模块(子利用),如何实现呢?

对于路由

qiankun 在主利用初始化会主动监听路由的变动去匹配注册好的子利用路由流动规定,同时 vue 路由也会监听路由变动。

因为主利用有本人的业务模块,须要反对页面刷新,所以采纳 hash 路由模式。qiankun 官网 demo 应用的是 history 路由模式。

那么,采纳 hash 路由模式的话,主利用路由会有 /#/ 的前缀,比方主利用的 resource 组件路由:

http://localhost:8889/#/resource

假如 history 路由模式下子利用的注册信息为:

{  name: 'live',  entry: '//localhost:7102',  container: '#subapp-viewport',  activeRule: '/live',}

此时 qiankun 只有命中 urlhttp://localhost:8889/live 才会加载子利用。

此处假如应用的路由切换代码为:

this.$router.push({  path: '/live'})

所以当初切换的 urlhttp://localhost:8889/#/live,显然不能匹配 /live,所以加载子利用失败。咱们须要批改一下子利用注册的 activeRule,使得匹配 hash 路由模式。

为了辨别开主利用的本身模块与子利用的路由区别,子利用的路由减少 /micro 前缀,比方 /micro/live 是子利用的路由。

那么 hash 路由模式下子利用的注册信息变成:

{  name: 'live',  entry: '//localhost:7102',  container: '#subapp-viewport',  activeRule: '/#/micro/live',}

路由切换代码批改为:

this.$router.push({  path: '/micro/live'})

这样的话,主利用路由切换后的 url 就能命中子利用的 activeRule 了。

同时,子利用也须要将路由模式设置为 hash 模式,否则,会呈现在子利用切换本身路由时,扭转主利用 hash 路由的状况。比方子利用切换本身路由 /about,此时 url 会变成 http://localhost:8889/about/#/micro/live,导致路由命中失败。咱们冀望的 urlhttp://localhost:8889/#/micro/live/about

所以,为了兼容主利用的 hash 模式路由,子利用也须要设置为 hash 模式的路由,最终后果是实现子利用路由与子利用注册在主利用的 activeRule 的一致性。

上面会别离对主利用与子利用进行配置。

配置子利用路由

子利用是惯例 vue 我的项目,须要做调整的的是路由配置文件 /router.index.js 以及入口文件 main.js

// router/index.jslet prefix = ''// 判断是 qiankun 环境则减少路由前缀if(window.__POWERED_BY_QIANKUN__){  prefix = '/micro/live'}const routes = [  {    path: prefix + '/',    name: 'home',    component: Home,  },  {    path: prefix +'/about',    name: 'about',    component: About  },]
// main.jslet router = null;let instance = null;function render(props = {}) {  const { container } = props;  router = new VueRouter({    // 默认为 hash 路由模式    // base: window.__POWERED_BY_QIANKUN__ ? '/micro/live' : '/',    // mode: 'history',    routes,  })  // 判断 qiankun 环境则进行路由拦挡,判断跳转路由是否有 /micro 结尾前缀,没有则加上  if(window.__POWERED_BY_QIANKUN__){    router.beforeEach((to, from, next) => {      if(!to.path.includes('/micro')){        next({          path: '/micro/live' + to.path        })      }else{        next()      }    })  }  instance = new Vue({    router,    store,    render: h => h(App),  }).$mount(container ? container.querySelector('#app') : '#app');}

配置主利用路由

主利用须要批改的是子利用注册的路由匹配规定,因为主利用采纳的是 hash 路由模式,qiankun 须要命中路由的话,activeRule 须要带上 /#/ 前缀。

// App.vueconst apps = [  {    name: 'live',    entry: '//localhost:7101',    container: '#subapp-viewport',    activeRule: '/#/micro/live',  }]registerMicroApps(apps,   {    beforeLoad: [      app => {        console.log('[LifeCycle] before load %c%s', 'color: green;', app.name);      },    ],    beforeMount: [      app => {        console.log('[LifeCycle] before mount %c%s', 'color: green;', app.name);      },    ],    afterUnmount: [      app => {        console.log('[LifeCycle] after unmount %c%s', 'color: green;', app.name);      },    ],  },)
// router/index.js// httpRoutes 非必要,次要用于匹配 vue 利用路由,与路由通配符 {path: '*'} 一起应用// 因为如果 vue 路由没有匹配,默认是加载 Home 组件的// 这样 vue 路由视图会与子利用共存,不合乎业务需要//// 以后 httpRoutes 的路由配置是没有设置 path 对应的组件,所以匹配的路由视图必为空//// 如果不设置路由通配符,则 httpRoutes 不须要配置const httpRoutes = [  {    path: '/micro/live',    name: 'Live'    // 没有配置 component,则 router-view 不会加载组件  },  {    path: '/micro/live/:microRoute',    name: 'Live*'    // 没有配置 component,则 router-view 不会加载组件  }]const router = new VueRouter({  routes: [    {      path: '/',      name: 'Home',      component: Home,    },    ...httpRoutes,    {      path: '*',      component: Home    }  ]})

url 变动时,首先主利用进入的是 qiankun 的路由匹配规定,匹配到 /#/micro/live 时,会加载子利用,同时主利用的 vue 路由匹配到路由后不会加载路由组件,这样就达到只显示子利用而 vue 路由组件不显示的目标。

当子利用外部的 <router-link to="/about"> 被点击时,首先子利用跳转路由前会加上 /micro/live 前缀,实际上是 /micro/live/about,匹配到 about 路由,而后在主利用的 vue 路由中匹配到 /micro/live:microRoute,同样不会加载组件。

本文参考:前端微服务(qiankun)哈希路由实际

往期系列文章

qiankun 微前端利用实际与部署

qiankun 微前端利用实际与部署(二)

qiankun 微前端利用实际与部署(三)