qiankun 微前端应用实践与部署(三)

微前端架构下,主应用有自己的路由模块,同时主应用支持以微前端的方式嵌入业务模块(子应用),如何实现呢?

关于路由

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.js

let 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.js

let 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.vue

const 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 微前端应用实践与部署(三)

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,504评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,434评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,089评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,378评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,472评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,506评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,519评论 3 413
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,292评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,738评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,022评论 2 329
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,194评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,873评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,536评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,162评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,413评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,075评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,080评论 2 352