qiankun路由模式实践与总结

956 阅读3分钟

总结一下 qiankun 微前端项目下,主应用和微应用的路由模式如何进行配置,用一个简单的 以 vue2为框架的demo 进行分享,主应用和微应用都采用 vue2 框架进行搭建

主应用和微应用的配置就不再进行讲解,可以看下 qiankunjs微前端框架详解

主应用和微应用都选择 history 模式

主应用:

// 注册微应用 src/main.js
const apps = [
  {
    name: 'vue-child', // app name registered
    entry: '//localhost:8081',
    container: '#child-container',
    activeRule: '/child/vue-child',
    props: {}, // 初始化时需要传递给微应用的数据
  }
]
registerMicroApps(apps);

start()


// 路由 src/router/index.js

const routes = [
  {
    path: '/',
    name: 'home',
    component: HomeView,
    redirect: 'main-list',
    children: [
      {
        path: "main-list",
        name: "main-list",
        component: MainList
      },
      {
        path: "AboutView",
        name: "AboutView",
        component: AboutView
      }
    ]
  },
  {
    path: '/child/*',
    name: 'child',
    component: HomeView
  }
]

const router = new VueRouter({
  mode: 'history',
  base: '/',
  routes
})

export default router


// 总体布局 - HomeView页面
<template>
  <div class="main-content">
    <el-header>
      <MainHeader />
    </el-header>
    <el-container>
      <el-aside width="200px">
        <!-- <MainMenu /> -->
        <el-row class="tac">
          <el-col :span="24">
            <el-menu
              router
              default-active="main-list"
              class="el-menu-vertical-demo"
              @open="handleOpen"
              @close="handleClose"
              background-color="#545c64"
              text-color="#fff"
              active-text-color="#ffd04b">
              <el-menu-item index="/main-list">
              <i class="el-icon-location"></i>
              <span slot="title">主应用</span>
              </el-menu-item>
              <el-menu-item index="/AboutView">
                <i class="el-icon-menu"></i>
                <span slot="title">主应用子页面</span>
              </el-menu-item>
              
              <!-- 当前演示所用微应用 -->
              <el-menu-item index="/child/vue-child/">
                <i class="el-icon-document"></i>
                <span slot="title">子应用一</span>
              </el-menu-item>
              
              
            </el-menu>
          </el-col>
        </el-row>
      </el-aside>
      <el-main>
        <!-- 渲染微应用所用容器 -->
        <div id="child-container"></div>
        
        <!-- 用来渲染主应用页面 -->
        <router-view />
      </el-main>
    </el-container>    
  </div>
</template>

注册路由的时候需要进行路由通配(即 /child/*),因为我所选择的是在某个路由页面加载的微应用,所以要进行路由通配,可以查看官网 如何在主应用的某个路由页面加载微应用,如果不进行路由通配,会报错容器未找到

image.png

可以在官网的常见问题中查看此错误 Application died in status NOT_MOUNTED: Target container with #container not existed while xxx loading!

微应用:

// 路由文件 src/router/index.js

const routes = [
  {
    path: '/',
    redirect: '/child-page'
  },
  {
    path: '/home',
    name: 'home',
    component: HomeView
  },
  {
    path: '/child-page',
    name: 'childPage',
    component: childPage
  }
]

const router = new VueRouter({
  mode: 'history',
  base: window.__POWERED_BY_QIANKUN__ ? '/child/vue-child' : '/', // 基础路径
  routes
})

export default router

微应用中路由的 base 要与主应用中注册微应用时的 activeRule 配置一致,activeRule 就是设置的微应用的路由匹配规则

主应用和微应用都使用 hash 模式

主应用配置

// src/router/index.js

// ...
const router = new VueRouter({
  mode: 'hash
  base: '/',
  routes
})

export default router


// 注册微应用时 修改activeRule属性
// src/main.js
const Apps = [
  {
    name: 'vue-child',
    entry: '//localhost:8081',
    container: '#child-container',
    activeRule: '#/child/vue-child'
  }
]
registerMicroApps(Apps);

微应用配置

// src/router/index.js
const routes = [
  {
    path: '/child/vue-child',
    redirect: '/child/vue-child/child-page'
  },
  {
    path: '/child/vue-child/home',
    name: 'home',
    component: HomeView
  },
  {
    path: '/child/vue-child/child-page',
    name: 'childPage',
    component: childPage
  }
]

// 也可以新建一个 /child/vue-child 其余路由作为children
const routes = [
    {
        path: '/child/vue-child',
        children: [
            // 其余路由放到这里
            {
                path: 'home',
                name: 'home',
                component: HomeView,
            },
            // ...
        ]
    }
]

const router = new VueRouter({
  mode: 'hash',
  base: window.__POWERED_BY_QIANKUN__ ? '/child/vue-child' : '/', //基础路径
  routes
})

export default router

微应用路由 base 相对于 history 模式下不需要做修改,只需要在 routes 中的每个路由都加上 base 值作为前缀即可,即/ --> /child/vue-child /child-page --> /child/vue-child/child-page

主应用使用 history 模式,微应用使用 hash 模式

此种模式下的配置与主应用和微应用都采用history 模式下配置一致

主应用使用 hash 模式,微应用使用 history 模式

此种路由模式下会出现很多问题,试了很多种方法,例如跳转不成功、路由爆栈、切换其他主应用下的界面时,微应用未卸载,导致携带上了微应用的路由,或者直接把微应用的页面和主应用下的子页面共同展示出来、跳转成功但是路由臃肿等问题。

看了下 qiankungithub issues 有同学分享出此种模式下需要进行兼容,即微应用也需要切换 hash 路由模式,否则会出现微应用切换自身路由时,改变主应用 hash 路由的情况, 例如:微应用切换自身路由 /about, 此时 url 会变成 http://localhost:8080/about/#/micro/live。而我们期望的路由是 http://localhost:8080/#/micro/live/about

详细可以看下这里 --> qiankun issues 24

目前还在测试,等测试出来了会贴图分享,如果有测试出来的小伙伴可以在评论区分享下demo