qiankun + Vue实现微前端服务

本文介绍如何使用qiankun + Vue搭建一个前端微服务

一、什么是微前端

Techniques, strategies and recipes for building a modern web app with multiple teams that can ship features independently. -- Micro Frontends
微前端是一种多个团队通过独立发布功能的方式来共同构建现代化 web 应用的技术手段及方法策略。

以上内容均来自于 qiankun手册,有兴趣可以也看看这个api文档,很多关于微前端的困惑都在里面,以及为什么是不用iframe等....
本文代码,可以直接食用:qiankun-demo
效果:

微前端效果.gif

二、创建应用

在本例子中,我们需要通过vue-cli创建创建一个主应用,两个子应用。
目录结构:

|——qiankun-demo // 主文件夹
|——|——child-app01 //子应用1
|——|——child-app02 //子应用2
|——|——main-app //主应用
|——|——server.js // 自己写的一个快捷启动服务脚本,手动启动服务的可以忽略
|——|——package.js // 脚本依赖,手动启动服务的可以忽略

三、应用配置

主应用相关代码:

qiankun是通过registerMicroApps(apps, lifeCycles)API来注册子应用的,在main-app目录下

npm install qiankun -S
npm install element-ui -S // 引入element快速实现样式

main.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(element);
import { registerMicroApps, start } from 'qiankun'

Vue.config.productionTip = false

const microAppNum = 2
let apps = [];
for (let i = 1; i <= microAppNum; i++) {
  apps.push(
    {
      name: '子应用child0' + i,
      entry: 'http://localhost:90' + i + '0',
      //fetch,
      container: '#vue',
      activeRule: '/child0' + i,
      props: { param01: i }
    }
  );
}
const config = {
    beforeLoad: [
        app => {
            console.log("%c before load",
            'background:#0f0 ; padding: 1px; border-radius: 3px;  color: #fff',
            app);
        }
    ], // 挂载前回调
    beforeMount: [
        app => {
            console.log("%c before mount",
            'background:#f1f ; padding: 1px; border-radius: 3px;  color: #fff',
            app);
        }
    ], // 挂载后回调
    afterUnmount: [
        app => {
            console.log("%c after unload",
            'background:#a7a ; padding: 1px; border-radius: 3px;  color: #fff',
            app);
        }
    ] // 卸载后回调
  }
registerMicroApps(apps, config);
let option = { prefetch: false }
start();


new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
  • 如果暂时不需要看到生命周期的输出,可以不定义config,同时注册应该时registerMicroApps(apps, config);把里面的config去掉即可
  • 其中的container内的#vue,对应app.vue内的id="vue"元素块

vue.config.js

若不存在该文件,新建一个vue.config.js

module.exports = {
    devServer: {
        port: 9000,
        headers: {
            //'Access-Control-Allow-Origin': "*"
        }
    }
};

App.vue

利用引入的element,快速搭建一个简单的页面

<template>
  <div>
    <el-menu :router="true" mode="horizontal">
      <el-menu-item index="/">首页</el-menu-item>
      <el-menu-item v-for="no in  microAppNum" :key="no" :index="'/child0'+no">子应用0{{no}}</el-menu-item>
    </el-menu>
    <router-view />
    <!-- 子应用入口 -->
    <div id="vue"></div>
  </div>
</template>

<script>
export default {
  name: "main01",
  data() {
    return {
      microAppNum: 2
    };
  },
};
</script>

子应用配置

mian.js

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'

// Vue.config.productionTip = false

let install = null;
function render(props) {
  install = new Vue({
    router,
    store,
    render: h => h(App)
  }).$mount('#app')
}
if (window.__POWERED_BY_QIANKUN__) {
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
} else {
  render();
}
export async function bootstrap(props) {

}

export async function mount(props) {
  render(props);
}
export async function unmount(props) {
  install.$destroy();
}

vue.config.js

同样,在该文件内,

const port = 9010; // 一个应用写9010,另一个写9020
module.exports = {
    devServer: {
        port,
        headers: {
            'Access-Control-Allow-Origin': '*'
        }
    },
    configureWebpack: {
        output: {
            library: 'child',
            libraryTarget: 'umd'
        }
    }
};

子应用必须支持跨域:由于 qiankun 是通过 fetch 去获取子应用的引入的静态资源的,所以必须要求这些静态资源支持跨域;

本地服务直接在vue.config.js内配上跨域相关即可,上线的话,需要在服务器配置白名单。后续文章将更新跟打包相关内容。

/router/index.js

这里需要特别注意,我们在父应用注册微服务的时候,写了相关activeRule,
所以子应用路由这边配置也要相应的修改


image.png

四、使用

分别进入父子应用目录

npm run serve

全部启动后,可以单独打开子应用,看到页面,也可以在主应用内,直接看到里面的子应用,效果类似iframe。

发现服务启动,因为代码端口写死,若端口冲突,可以关闭端口重新启动服务,或者修改代码。

由于我不想每次都进入父子应用目录,去重复启动多个服务,手动写了一个node脚本,去快速启动三个服务,可以手动启动服务的,可忽略该脚本,分别手动启动三个服务即可。

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