qiankun乾坤微前端,使用vue从零搭建完整示例

前言

最近正在开发项目,正好用的qiankun搭建的框架,找时间从新开始搭建了一个示例项目,研究了一下基础应用,分享一下附上代码地址,希望对大家有帮助,有问题可以留言交流

项目github地址:

https://github.com/yuzhenyou/qiankun

qiankun乾坤微前端示例

项目说明

主应用和子应用都是通过Vue-cli工具构建,vue2版本项目

  • qiankun-main 为主应用

  • qiankun-app 为子应用

基本项目结构

[图片上传失败...(image-913b04-1651243721932)]

一、主应用配置说明(qiankun-main)

src/micros/apps.js 为子应用路由规则


const apps = [

    /**

    * name: 微应用名称 - 具有唯一性

    * entry: 微应用入口 - 通过该地址加载微应用

    * container: 微应用挂载节点 - 微应用加载完成后将挂载在该节点上

    * activeRule: 微应用触发的路由规则 - 触发路由规则后将加载该微应用

    */

    {

        name: "qiankun-app",

        entry: "//localhost:8001/qiankun-app",

        container: "#app",

        activeRule: "/qiankun-app"

    }

];

export default apps;

src/micros/index.js 为子应用注册主入口


import { registerMicroApps, addGlobalUncaughtErrorHandler, start } from "qiankun";

import apps from "./apps";

/**

* @description: 注册微应用

* 第一个参数 - 微应用的注册信息

* 第二个参数 - 全局生命周期钩子

*/

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);

                location.reload(true)

            },

        ],

    }

);

addGlobalUncaughtErrorHandler((event) => {

    const { msg } = event;

    if (msg && msg.includes('died in status LOADING_SOURCE_CODE')) {

        console.log('加载失败');

    }

});

/**

* @description: 导出启动函数

*/

export default start;

src/router/index.js 主路由(base根据实际情况自行修改)


import Vue from 'vue'

import Router from 'vue-router'

Vue.use(Router)

const Index = resolve => require(['@/views/index'], resolve)

const routes = [

    {

        path: '/',

        name: '主页',

        component: Index

    }

]

const router = new Router({

    base: "/qiankun-main", //配合nginx生产发布https://xxx.com//qiankun-main具体根据部署动态修改

    mode: 'history',

    routes

})

export default router

src/main.js 主文件配置


import Vue from 'vue'

import store from './store';

import router from "./router";

import App from './App.vue'

Vue.config.productionTip = false

new Vue({

    router,

    store,

    render: h => h(App),

}).$mount('#app')

//引入qiankun注册文件

import startQiankun from "./micros";

//启动微应用

startQiankun();

微应用跳转


<template>

  <div class="home">

    <h3 @click="push('/qiankun-app')">click to qiankun-app !!!</h3>

  </div>

</template>

<script>

export default {

  methods: {

    push(subapp) {

      history.pushState(null, subapp, subapp);

    },

  },

};

</script>

二、子应用配置说明(qiankun-app)

src/public-path.js 为子应用环境变量,用于判断主应用进入时的url地址

*根路径项目webpack_public_path = window.INJECTED_PUBLIC_PATH_BY_QIANKUN

*本项目子应用router base为qiankun-app故添加了‘qiankun-app/’后缀,根据项目自行修改

webpack_public_path = window.INJECTED_PUBLIC_PATH_BY_QIANKUN + 'qiankun-app/'


// 1.修改运行时的public-path 主要解决的是微应用动态载入的 脚本、样式、图片 等地址不正确的问题。

if (window.__POWERED_BY_QIANKUN__) {

    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__ + 'qiankun-app/';

    console.log('__webpack_public_path__', __webpack_public_path__)

}

src/router/index.js 主路由(base根据实际情况自行修改)


import Vue from 'vue'

import Router from 'vue-router'

Vue.use(Router)

const Index = resolve => require(['@/views/index'], resolve)

const About = resolve => require(['@/views/about.vue'], resolve)

const routes = [

    {

        path: '/',

        name: 'index',

        component: Index

    },

    {

        path: '/about',

        name: 'about',

        component: About

    }

]

const router = new Router({

    base: '/qiankun-app', // 如果作为乾坤的子应用则使用主应用中配置的路由前缀,如果是独立运行则使用根目录

    mode: 'history',

    routes

})

export default router

src/main.js 主文件配置


import Vue from 'vue'

import App from './App.vue'

import router from "./router";

Vue.config.productionTip = false

let instance = null;

// 重新包装render方法

function render(props = {}) {

    const { container } = props;

    const renderContainer = container ? container.querySelector('#app') : '#app'; // 如果是作为子应用渲染,则渲染到主应用中配置的DOM节点中

    console.log('renderContainer', renderContainer)

    instance = new Vue({

        router,

        render: h => h(App)

    }).$mount(renderContainer);

}

//引入乾坤加载路径

import './public-path';

// 独立运行时直接渲染

if (!window.__POWERED_BY_QIANKUN__) {

    render();

}

export async function bootstrap() {

    console.log('[vue] vue app bootstraped');

}

export async function mount(props) {

    console.log('[vue] props from main framework', props);

    render(props); // 作为子应用渲染时将主应用传入的配置作为参数去渲染

}

export async function unmount() {

    instance.$destroy();

    instance.$el.innerHTML = '';

    instance = null;

}

三、vue.config.js配置说明


const path = require('path');

function resolve(dir) {

    return path.join(__dirname, dir);

  }

const { name } = require('./package');

module.exports = {

    publicPath: `/${name}`,

    lintOnSave: false,

    devServer: {

        port: 8000,

        // 关闭主机检查,使微应用可以被 fetch,否则会提示生命周期未注册

        // disableHostCheck: true,

        // 配置跨域请求头,解决开发环境的跨域问题

        headers: {

            'Access-Control-Allow-Origin': '*',

        },

    },

    configureWebpack: {

        resolve: {

            alias: {

                '@': resolve('src'),

            },

        },

        output: {

            library: `${name}-[name]`,

            libraryTarget: 'umd', // 把微应用打包成 umd 库格式

            // jsonpFunction: `webpackJsonp_${name}`, //webpack5废弃jsonpFunction

            chunkLoadingGlobal: `webpackJsonp_${name}`,

        },

    }

}

四、常见问题参考官方说明

https://qiankun.umijs.org/zh/faq

  1. 注意子应用mian.js必须导出生命周期

  2. 注意public-path.js的路径是否正确

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

推荐阅读更多精彩内容