前言
流程
vue create child-vue
vue create parent-vue
- 同样history路由。
- 我们需要让父应用加载子应用。
- 子应用安装single-spa-vue
- 然后改写main.js ,需要导出3个方法,供父应用调用。
import Vue from 'vue'
import App from './App.vue'
import router from './router'
import singleSpaVue from 'single-spa-vue'
Vue.config.productionTip = false
const appOptions ={
el:'#vue',
router,
render:h=>h(App)
}
const vueLifeCircle = singleSpaVue({
Vue,
appOptions
})
export const bootstrap =vueLifeCircle.bootstrap
export const mount = vueLifeCircle.mount
export const unmount =vueLifeCircle.unmount
- 改写子应用Webpack vue.config.js 打包成一个lib:
module.exports = {
configureWebpack: {
output: {
library: "singleVue",
libraryTarget: "umd",
},
devServer: {
port: 10000,
},
},
};
- 启动子应用,查看控制台network发现app.js已经作为了umd应用。另外还有个chunk-vendors.js。
- 父应用安装single-spa,修改app.vue:
<template>
<div id="app">
<router-link to="/vue">加载vue应用</router-link>
<div id="vue"></div>
</div>
</template>
<style></style>
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import { registerApplication, start } from "single-spa";
Vue.config.productionTip = false;
registerApplication(
"myVueApp",
async () => {
console.log("加载");
return;
},
(location) => location.pathname.startsWith("/vue")
);
new Vue({
router,
render: (h) => h(App),
}).$mount("#app");
import Vue from "vue";
import App from "./App.vue";
import router from "./router";
import { registerApplication, start } from "single-spa";
Vue.config.productionTip = false;
async function loadScript(url) {
return new Promise((res, rej) => {
let script = document.createElement("script");
script.src = url;
script.onload = res;
script.onerror = rej;
document.head.appendChild(script);
});
}
registerApplication(
"myVueApp",
async () => {
await loadScript("http://localhost:10000/js/chunk-vendors.js");
await loadScript("http://localhost:10000/js/app.js");
return window.singleVue;
},
(location) => location.pathname.startsWith("/vue")
);
start();
new Vue({
router,
render: (h) => h(App),
}).$mount("#app");
- 此时点击切换,已经可以发现子应用出现了,但是路由不对。
- 这时切换子应用,修改子应用的baseurl 为/vue 跟父应用的/vue对应。
const router = new VueRouter({
mode: "history",
base: "/vue",
routes,
});
- 再次打开父应用,切换子应用路由, 此时图片都已经渲染出来,但是加载about路由仍会报错。
- about会加载8080的about而不是10000的about。
- 子应用中修改webpack的public path:
if (window.singleSpaNavigate) {
__webpack_public_path__ = "http://localhost:10000/";
}
- 此时打开切换子应用的about,实现了加载子应用的about页面。
- 子应用目前无法独立运行,所以同样做个判断,如果没有这个变量,说明是独立运行,那么就挂载:
if (!window.singleSpaNavigate) {
delete appOptions.el;
new Vue(appOptions).$mount("#app");
}
- 这样就使得父应用能挂载子应用,子应用也可以独立运行了。