一路的搬砖心里历程,官方文档才是亲爸爸,so,官方的文档:qiankun.umijs.org/zh/guide/ge…
接触qiankun一开始直白的疑惑
1.主应用如何跳转子应用
2.子应用如何知道自己是在qiankun的环境中并且拿到主应用的登录信息等
3.子应用如何反向传递数据给主应用
<1.在主应用中注册微应用>
1.根据路由规则匹配注册应用 (url 发生变化自动触发 qiankun 的匹配逻辑,所有 activeRule 规则匹配上的微应用就会被插入到指定的 container 中,同时依次调用微应用暴露出的生命周期钩子)
import { registerMicroApps, start } from 'qiankun';
registerMicroApps([
{
name: 'app', // app name registered
entry: '//localhost:7100',
container: '#yourContainer',
activeRule: '/yourActiveRule',
},
{
name: 'vue app',
entry: { scripts: ['//localhost:7100/main.js'] },
container: '#yourContainer2',
activeRule: '/yourActiveRule2',
},
]);
start();
2.手动加载微应用
import { loadMicroApp } from 'qiankun';
loadMicroApp({
name: 'app',
entry: '//localhost:7100',
container: '#yourContainer',
});
----------------------------------------注意点-----------------------------------------
entry:除了是本地之外,也可以直接服务器访问网址。
activeRule:注意路由base
container: 需在 APP.vue 中添加 `#yourContainer` eg:<div id="yourContainer"></div>
主应用跳转:
this.$router.push({
path: 'url'
})
子应用跳转主:
window.history.pushState(state, title, url); // state 数据(可选)title 标题(可选)url 路径 必填
<2.子应用改造>
1.在 src 目录新增 public-path.js:
if (window.__POWERED_BY_QIANKUN__) {
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
2.入口文件 main.js 修改,为了避免根 id #app 与其他的 DOM 冲突
import './public-path';
import Vue from 'vue';
import VueRouter from 'vue-router';
import App from './App.vue';
import routes from './router';
import store from './store';
Vue.config.productionTip = false;
let router = null;
let instance = null;
function render(props = {}) {
const { container } = props;
router = new VueRouter({
base: window.__POWERED_BY_QIANKUN__ ? '/app-vue/' : '/',
mode: 'history',
routes,
});
instance = new Vue({
router,
store,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#app') : '#app');
}
// 独立运行时
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;
router = null;
}
3.打包配置修改(vue.config.js):
const { name } = require('./package');
module.exports = {
devServer: {
headers: {
'Access-Control-Allow-Origin': '*',
},
},
configureWebpack: {
output: {
library: `${name}-[name]`,
libraryTarget: 'umd', // 把微应用打包成 umd 库格式
jsonpFunction: `webpackJsonp_${name}`,
},
},
};
<3.主应用及子应用传值>
1.父应用向子应用传递
<1.>注册路由时 props: {} 直接在子应用mount(props)拿到相关的传递的值
<2.>子应用在 `mount` 函数中接受 `props` 参数,通过 `onGlobalStateChange` 函数监听主应用传递过来的值
主:
import { initGlobalState } from 'qiankun'
let global = initGlobalState({isApp:''})
global.setGlobalState({isApp:true})
子:
props.onGlobalStateChange( state => {
console.log('主应用数据',state)
}, true);
2.子应用向主应用传值
子:
props.setGlobalState({a:'我来了'})
父:
global.onGlobalStateChange(state => {
// 监听全局状态,子应用更新主应用数据后触发
console.log(state)
})
注意:一般不混乱增强可阅读性,增加单独管理actions.js
function emptyAction() {
console.warn("action is empty!");
}
class Actions {
actions = {
onGlobalStateChange: emptyAction,
setGlobalState: emptyAction,
};
setActions(actions) {
this.actions = actions;
}
onGlobalStateChange(...args) {
return this.actions.onGlobalStateChange(...args);
}
setGlobalState(...args) {
return this.actions.setGlobalState(...args);
}
}
const actions = new Actions();
export default actions;
尾记:解开了迷惑,qiankun也就处在了可上手状态,另外关于qiankun的js沙箱隔离,css样式隔离未尝试,希望有宝子能够指点一二