micro-app 简介
微前端的概念是由ThoughtWorks在2016年提出的,它借鉴了微服务的架构理念,核心在于将一个庞大的前端应用拆分成多个独立灵活的小型应用,每个应用都可以独立开发、独立运行、独立部署,再将这些小型应用融合为一个完整的应用,或者将原本运行已久、没有关联的几个应用融合为一个应用。微前端既可以将多个项目融合为一,又可以减少项目之间的耦合,提升项目扩展性,相比一整块的前端仓库,微前端架构下的前端仓库倾向于更小更灵活。
主应用配置
使用方法
创建vue2或3项目
vue create master-file
安装micro-app
npm i @micro-zoe/micro-app --save
进入main.js文件
// vue2
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import VueRouter from "vue-router";
import microApp from "@micro-zoe/micro-app";
Vue.config.productionTip = false;
microApp.start();
new Vue({
router,
render: (h) => h(App),
}).$mount("#app");
// vue3
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import * as echarts from 'echarts'
import microApp from "@micro-zoe/micro-app";
microApp.start();
const app = createApp(App)
app.config.globalProperties.$echarts = echarts
app.use(store).use(router).mount('#app')
分配一个路由给子应用(views新建my-page.vue)
// vue2
import Vue from "vue";
import VueRouter from "vue-router";
import MyPage from "../views/my-page.vue";
Vue.use(VueRouter);
const routes = [
{
// 👇👇👇👇👇 非严格匹配,/my-page/* 都指向 MyPage 页面
path: "/my-page/*",
name: "my-page",
component: MyPage,
},
];
const router = new VueRouter({
mode: "history",
// 设置主应用基础路由为main-vue(用于后续部署),则子应用基础路由(baseroute)为/main-vue/xxx
base: process.env.BASE_URL,
routes,
});
export default router ;
// vue3
import { createRouter, createWebHashHistory } from 'vue-router'
const routes = [
{
// 👇👇👇👇👇 非严格匹配,/my-page/* 都指向 MyPage 页面
path: "/my-page/*",
name: "my-page",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/my-page.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),
base: process.env.BASE_URL,
routes
})
export default router
在my-page.vue上嵌入子应用
// vue2和vue3都一样
<template>
<div>
<h1>子应用</h1>
<!--
name(必传):应用名称
url(必传):应用地址,会被自动补全为http://localhost:3000/index.html
baseroute(可选):基座应用分配给子应用的基础路由,就是上面的 `/my-page`
-->
<micro-app name='app1' url='http://localhost:3000/' baseroute='/my-page'></micro-app>
</div>
</template>
主应用配置完毕!
子应用配置
创建 vue 子应用
vue create childs-vue
在src同级文件创建vue.config.js
// vue.config.js
module.exports = {
devServer: {
port: 3000,
headers: {
"Access-Control-Allow-Origin": "*",
},
},
};
在router文件夹 index.js
//vue2
import Vue from "vue";
import VueRouter from "vue-router";
import Home from "../views/Home.vue";
Vue.use(VueRouter);
const routes = [
{
path: "/",
name: "Home",
component: Home,
},
{
path: "/about",
name: "About",
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () =>
import(/* webpackChunkName: "about" */ "../views/About.vue"),
},
];
const router = new VueRouter({
mode: "history",
// 👇👇👇👇👇 __MICRO_APP_BASE_ROUTE__ 为micro-app传入的基础路由
base: window.__MICRO_APP_BASE_ROUTE__ || process.env.BASE_URL,
routes,
});
export default router;
// vue3
import { createRouter, createWebHashHistory } from 'vue-router'
import Home from '../views/Home.vue'
const routes = [
{
path: '/',
name: 'Home',
component: Home
},
{
path: '/about',
name: 'About',
// route level code-splitting
// this generates a separate chunk (about.[hash].js) for this route
// which is lazy-loaded when the route is visited.
component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')
}
]
const router = createRouter({
history: createWebHashHistory(),
base: window.__MICRO_APP_BASE_ROUTE__ || process.env.BASE_URL,
routes
})
export default router
})
在src里新建文件public-path.js
//public-path.js
// __MICRO_APP_ENVIRONMENT__和__MICRO_APP_PUBLIC_PATH__是由micro-app注入的全局变量
if (window.__MICRO_APP_ENVIRONMENT__) {
// eslint-disable-next-line
__webpack_public_path__ = window.__MICRO_APP_PUBLIC_PATH__
}
把 public-path.js引入main.js
// vue2 就不写了 都一样的
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
// 引入public-pathk.js
import './public-pathk'
createApp(App).use(store).use(router).mount('#app')
卸载监听
// main.js
// vue2
import "./public-path"; // 必须放在第一个要不然图片不显示
import Vue from "vue";
import App from "./App.vue";
import VueRouter from "vue-router";
import router from "./router";
Vue.config.productionTip = false;
const app = new Vue({
router ,
render: (h) => h(App),
}).$mount("#app");
// 监听卸载操作
window.addEventListener("unmount", function () {
app.$destroy();
});
// vue3
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './public-pathk'
createApp(App).use(store).use(router).mount('#app')
window.addEventListener("unmount", function () {
App.$destroy();
})