17 changed files with 319 additions and 66 deletions
@ -1,8 +1,56 @@
@@ -1,8 +1,56 @@
|
||||
import Vue from 'vue' |
||||
import App from './App.vue' |
||||
import VueRouter from 'vue-router'; |
||||
|
||||
Vue.config.productionTip = false |
||||
let router = null; |
||||
let instance = null; |
||||
|
||||
new Vue({ |
||||
render: h => h(App), |
||||
}).$mount('#app') |
||||
function render(props = {}) { |
||||
const { container } = props; |
||||
router = new VueRouter({ |
||||
base: window.__POWERED_BY_QIANKUN__ ? '/vue' : '/', |
||||
mode: 'history', |
||||
}); |
||||
|
||||
instance = new Vue({ |
||||
router, |
||||
render: h => h(App), |
||||
}).$mount(container ? container.querySelector('#app') : '#app'); |
||||
} |
||||
|
||||
if (!window.__POWERED_BY_QIANKUN__) { |
||||
render(); |
||||
} |
||||
|
||||
function storeTest(props) { |
||||
props.onGlobalStateChange && |
||||
props.onGlobalStateChange( |
||||
(value, prev) => console.log(`[onGlobalStateChange - ${props.name}]:`, value, prev), |
||||
true, |
||||
); |
||||
props.setGlobalState && |
||||
props.setGlobalState({ |
||||
ignore: props.name, |
||||
user: { |
||||
name: props.name, |
||||
}, |
||||
}); |
||||
} |
||||
|
||||
export async function bootstrap() { |
||||
console.log('[vue] vue app bootstraped'); |
||||
} |
||||
|
||||
export async function mount(props) { |
||||
console.log('[vue] props from main framework', props); |
||||
storeTest(props); |
||||
render(props); |
||||
} |
||||
|
||||
export async function unmount() { |
||||
instance.$destroy(); |
||||
instance.$el.innerHTML = ''; |
||||
instance = null; |
||||
router = null; |
||||
} |
||||
|
@ -1,4 +1,39 @@
@@ -1,4 +1,39 @@
|
||||
const { defineConfig } = require('@vue/cli-service') |
||||
|
||||
const path = require('path'); |
||||
const { name } = require('./package'); |
||||
|
||||
function resolve(dir) { |
||||
return path.join(__dirname, dir); |
||||
} |
||||
|
||||
const port = 7101; // dev port
|
||||
|
||||
module.exports = defineConfig({ |
||||
transpileDependencies: true |
||||
outputDir: 'dist', |
||||
assetsDir: 'static', |
||||
filenameHashing: true, |
||||
|
||||
transpileDependencies: true, |
||||
devServer: { |
||||
// host: '0.0.0.0',
|
||||
hot: true, |
||||
port, |
||||
headers: { |
||||
'Access-Control-Allow-Origin': '*', |
||||
}, |
||||
}, |
||||
// 自定义webpack配置
|
||||
configureWebpack: { |
||||
resolve: { |
||||
alias: { |
||||
'@': resolve('src'), |
||||
}, |
||||
}, |
||||
output: { |
||||
// 把子应用打包成 umd 库格式
|
||||
library: `${name}-[name]`, |
||||
libraryTarget: 'umd' |
||||
}, |
||||
}, |
||||
}) |
||||
|
@ -0,0 +1,25 @@
@@ -0,0 +1,25 @@
|
||||
/** |
||||
*微应用apps |
||||
* @name: 微应用名称 - 具有唯一性 |
||||
* @entry: 微应用入口.必选 - 通过该地址加载微应用, |
||||
* @container: 微应用挂载节点 - 微应用加载完成后将挂载在该节点上 |
||||
* @activeRule: 微应用触发的路由规则 - 触发路由规则后将加载该微应用 |
||||
*/ |
||||
import type { RegistrableApp } from 'qiankun'; |
||||
import { ComponentOptions } from '@vue/runtime-core'; |
||||
|
||||
//子应用列表
|
||||
const _apps: RegistrableApp<object>[] = []; |
||||
for (const key in import.meta.env) { |
||||
if (key.includes('VITE_APP_SUB_')) { |
||||
const name = key.split('VITE_APP_SUB_')[1]; |
||||
const obj = { |
||||
name, |
||||
entry: import.meta.env[key], |
||||
container: '#content', |
||||
activeRule: name, |
||||
}; |
||||
_apps.push(obj); |
||||
} |
||||
} |
||||
export const apps = _apps; |
@ -0,0 +1,68 @@
@@ -0,0 +1,68 @@
|
||||
/** |
||||
* qiankun配置 |
||||
*/ |
||||
import { registerMicroApps, setDefaultMountApp, start, runAfterFirstMounted, addGlobalUncaughtErrorHandler } from 'qiankun'; |
||||
import { apps } from './apps'; |
||||
import { getProps, initGlState } from './state'; |
||||
|
||||
/** |
||||
* 重构apps |
||||
*/ |
||||
function filterApps() { |
||||
apps.forEach((item) => { |
||||
//主应用需要传递给微应用的数据。
|
||||
item.props = getProps(); |
||||
//微应用触发的路由规则
|
||||
item.activeRule = genActiveRule('/' + item.activeRule); |
||||
}); |
||||
return apps; |
||||
} |
||||
|
||||
/** |
||||
* 路由监听 |
||||
* @param {*} routerPrefix 前缀 |
||||
*/ |
||||
function genActiveRule(routerPrefix) { |
||||
return (location) => location.pathname.startsWith(routerPrefix); |
||||
} |
||||
|
||||
/** |
||||
* 微应用注册 |
||||
*/ |
||||
function registerApps() { |
||||
const _apps = filterApps(); |
||||
registerMicroApps(_apps, { |
||||
beforeLoad: [ |
||||
(loadApp) => Promise.resolve(()=>{ |
||||
console.log('before load', loadApp); |
||||
}), |
||||
], |
||||
beforeMount: [ |
||||
(mountApp) => Promise.resolve(()=>{ |
||||
console.log('before mount', mountApp); |
||||
}), |
||||
], |
||||
afterMount: [ |
||||
(mountApp) => Promise.resolve(()=>{ |
||||
console.log('before mount', mountApp); |
||||
}), |
||||
], |
||||
afterUnmount: [ |
||||
(unloadApp) => Promise.resolve(()=>{ |
||||
console.log('after unload', unloadApp); |
||||
}), |
||||
], |
||||
}); |
||||
// 设置默认子应用,与 genActiveRule中的参数保持一致
|
||||
// setDefaultMountApp();
|
||||
// 第一个微应用 mount 后需要调用的方法,比如开启一些监控或者埋点脚本。
|
||||
runAfterFirstMounted(() => console.log('开启监控')); |
||||
// 添加全局的未捕获异常处理器。
|
||||
addGlobalUncaughtErrorHandler((event) => console.log(event)); |
||||
// 定义全局状态
|
||||
initGlState(); |
||||
//启动qiankun
|
||||
start({}); |
||||
} |
||||
|
||||
export default registerApps; |
@ -0,0 +1,39 @@
@@ -0,0 +1,39 @@
|
||||
/** |
||||
*公共数据 |
||||
*/ |
||||
import { initGlobalState, RegistrableApp } from 'qiankun'; |
||||
import { store } from '/@/store'; |
||||
import { router } from '/@/router'; |
||||
import { getAccessToken } from '/@/utils/auth'; |
||||
|
||||
//定义传入子应用的数据
|
||||
export function getProps(){ |
||||
return { |
||||
data: { |
||||
publicPath: '/', |
||||
token: getAccessToken(), |
||||
store, |
||||
router, |
||||
}, |
||||
}; |
||||
} |
||||
|
||||
/** |
||||
* 定义全局状态,并返回通信方法,在主应用使用,微应用通过 props 获取通信方法。 |
||||
* @param state 主应用穿的公共数据 |
||||
*/ |
||||
export function initGlState(info = { userName: 'admin' }) { |
||||
// 初始化state
|
||||
const actions = initGlobalState(info); |
||||
// 设置新的值
|
||||
actions.setGlobalState(info); |
||||
// 注册 观察者 函数 - 响应 globalState 变化,在 globalState 发生改变时触发该 观察者 函数。
|
||||
actions.onGlobalStateChange((newState, prev) => { |
||||
// state: 变更后的状态; prev 变更前的状态
|
||||
console.info('newState', newState); |
||||
console.info('prev', prev); |
||||
for (const key in newState) { |
||||
console.info('onGlobalStateChange', key); |
||||
} |
||||
}); |
||||
} |
Loading…
Reference in new issue