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: "*" ,
name: "sub~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: "single-host" */ "@/views/SingleHost.vue" ),
},
];
const router = new VueRouter ({
routes,
});
export default router;
< template >
< div ref = "host" / >
</ template >
< script >
import "systemjs/dist/system" ;
import "systemjs/dist/extras/use-default" ;
import {
start,
getAppStatus,
getAppNames,
registerApplication,
unregisterApplication,
triggerAppChange,
} from "single-spa/lib/esm/single-spa.dev.js" ;
export default {
name: "SingleHost" ,
watch: {
$route ( to , from ) {
if (to.fullPath !== from.fullPath) {
triggerAppChange ();
}
},
},
mounted () {
const apps = [
{
name: "sub1" ,
// publicPath: "http://127.0.0.1:8080/subs/sub1/",
publicPath: "http://127.0.0.1:8889/" ,
},
{
name: "sub2" ,
// publicPath: "http://127.0.0.1:8080/subs/sub1/",
publicPath: "http://127.0.0.1:8080/" ,
},
];
// 先根据路由找到最可能的子应用,然后加载+注册
const pre = apps. find (( v ) => location.hash. indexOf (v.name) > - 1 );
console. log ( "fetch" , pre);
this . loadManifest (pre)
. then (start)
. finally (() => {
console. log ( "prefetch all" );
Promise . all (apps. map (( app ) => this . loadManifest (app))). finally (start);
});
},
beforeDestroy () {
Promise . all ( getAppNames (). map (( app ) => unregisterApplication (app)));
},
methods: {
async loadManifest ( app ) {
return app && ! getAppStatus (app.name)
? window.System. import ( `${ app . publicPath }/manifest.json` ). then (
({ default : data }) => {
const { assets } = data.entrypoints.app;
registerApplication (
app.name,
() => this . loadChildAppJs (app.publicPath, assets),
( location ) => location.hash. startsWith ( `#/${ app . name }` ),
{
domElement: this .$refs.host,
}
);
}
)
: Promise . resolve ( true );
},
async loadChildAppJs ( publicPath , assets ) {
let appUrl;
try {
const jsPath = assets. filter (( v ) => v. endsWith ( ".js" )). pop ();
appUrl = publicPath + jsPath;
} catch (e) {
console. log (e);
}
console. log ( "loading" , appUrl);
return window.System. import (appUrl);
},
},
};
</ script >