1、第一种根据官方体统的action方式
基站
传:actions.setGlobalState
收:actions.onGlobalStateChange
import {
registerMicroApps,
addGlobalUncaughtErrorHandler,
start,
initGlobalState
} from 'qiankun' // 微应用注册信息
import apps from './app'
registerMicroApps(apps, {
beforeLoad: (app) => {
console.log('before load', app.name);
return Promise.resolve();
},
afterMount: (app) => {
console.log('after mount', app.name);
return Promise.resolve();
},
});
addGlobalUncaughtErrorHandler((event) => {
console.error(event);
const { message: msg } = event
if (msg && msg.includes('died in status LOADING_SOURCE_CODE')) {
console.error('微应用加载失败,请检查应用是否可运行')
}
});
const state = {}
const actions = initGlobalState(state)
//传参,在需要传递参数的地方直接调用
actions.setGlobalState({ path: '/resourcesCore/colonyManage', token: 121 })
//接收
actions.onGlobalStateChange((state, prev) => {
// state: 变更后的状态; prev 变更前的状态
console.log('基站',state, prev);
});
export { actions }
export default start
微服务,
传:props.setGlobalState
收:props.onGlobalStateChange
/*
* @Author: your name
* @Date: 2021-10-11 18:53:39
* @LastEditTime: 2021-11-07 22:59:43
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: /pm-ui/src/main.js
*/
import Vue from 'vue'
import Cookies from 'js-cookie'
import 'normalize.css/normalize.css' // a modern alternative to CSS resets
import Element from 'element-ui'
import './styles/element-variables.scss'
// import enLang from 'element-ui/lib/locale/lang/en'// 如果使用中文语言包请默认支持,无需额外引入,请删除该依赖
import '@/styles/index.scss' // global css
import App from './App'
import store from './store'
import router from './router'
import './icons' // icon
import './permission' // permission control
import './utils/error-log' // error log
// 清空表单
import resetForm from '../src/utils/resrtForm'
Vue.prototype.$resetForm = resetForm
// 数据的快速复制
import objCoppy from '../src/utils/objCoppy'
Vue.prototype.$objCoppy = objCoppy
// 信息提示框
import myconfirm from '../src/utils/myconfirm'
Vue.prototype.$myconfirm = myconfirm
import * as filters from './filters' // global filters
// 按钮权限判断
import hasPermission from '@/permission/index'
Vue.prototype.hasPerm = hasPermission
import httpRspCode from '@/utils/rspCode'
Vue.prototype.httpRspCode = httpRspCode
// 组件通讯工具
Vue.prototype.$EventBus = new Vue()
/**
* If you don't want to use mock-server
* you want to use MockJs for mock api
* you can execute: mockXHR()
*
* Currently MockJs will be used in the production environment,
* please remove it before going online ! ! !
*/
// if (process.env.NODE_ENV === 'production') {
// const { mockXHR } = require('../mock')
// mockXHR()
// }
// 自定义组件
import MyComponents from '@/components'
Vue.use(MyComponents)
Vue.use(Element, {
size: Cookies.get('size') || 'medium' // set element-ui default size
// locale: enLang // 如果使用中文,无需设置,请删除
})
// register global utility filters
Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key])
})
Vue.config.productionTip = false
// 新增:用于保存vue实例
let instance = null;
// 新增:动态设置 webpack publicPath,防止资源加载出错
if (window.__POWERED_BY_QIANKUN__) {
// eslint-disable-next-line no-undef
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
/** * 新增: * 渲染函数 * 两种情况:主应用生命周期钩子中运行 / 微应用单独启动时运行 */
function render(props = {}) {
console.log(props)
const { container,onGlobalStateChange } = props;
if(onGlobalStateChange){
setTimeout(()=>{
props.bus.$emit('setBusToken','456')
props.setGlobalState({ token: 'microActionToken' })
console.log(123)
},5000)
props.onGlobalStateChange((state, prevState) => {
// state: 变更后的状态; prev 变更前的状态
state.path ? router.push(state.path) : ''
console.log('通信状态发生改变:', state, prevState);
// 这里监听到globalToken变化再更新store
// store.commit('setToken', '******')
}, true);
}
// 挂载应用
instance = new Vue({
router,
store,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#micro-app-child') : '#micro-app-child');
}
/**
* 新增:
* bootstrap 只会在微应用初始化的时候调用一次,
下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap() {
console.log("VueMicroApp bootstraped");
}
/**
* 新增:
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props) {
console.log("VueMicroApp mount22", props);
setTimeout(()=>{
props.setGlobalState({ name: '基站' });
},2000)
render(props);
}
/**
* 新增:
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount() {
console.log("VueMicroApp unmount");
instance.$destroy();
instance = null;
}
// 新增:独立运行时,直接挂载应用
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// new Vue({
// el: '#app',
// router,
// store,
// render: h => h(App)
// })
第二种:vue的Eventbus
基站,定义eventbus,通过props的方式传入微服务
只看props.bus.$emit就好
import Vue from 'vue'
const bus = new Vue({
data: {
// 保持初始化时与store数据一致
// 基本类型可以这样用,引用类型请用cloneDeep深拷贝
// https://www.lodashjs.com/docs/lodash.cloneDeep#_clonedeepvalue
token: 123
}
})
Vue.prototype.$bus = bus
const apps = [
{
name: 'micro-app-order',
entry: '//localhost:9527',
container: '#order-container',
activeRule: '#/resourcesCore',
props: {
bus
}
}
]
export default apps
微服务入口文件接收并使用,并且可以动态 b u s . bus. bus.emit的方式传递值给基站
/*
* @Author: your name
* @Date: 2021-10-11 18:53:39
* @LastEditTime: 2021-11-07 22:59:43
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @FilePath: /pm-ui/src/main.js
*/
import Vue from 'vue'
import Cookies from 'js-cookie'
import 'normalize.css/normalize.css' // a modern alternative to CSS resets
import Element from 'element-ui'
import './styles/element-variables.scss'
// import enLang from 'element-ui/lib/locale/lang/en'// 如果使用中文语言包请默认支持,无需额外引入,请删除该依赖
import '@/styles/index.scss' // global css
import App from './App'
import store from './store'
import router from './router'
import './icons' // icon
import './permission' // permission control
import './utils/error-log' // error log
// 清空表单
import resetForm from '../src/utils/resrtForm'
Vue.prototype.$resetForm = resetForm
// 数据的快速复制
import objCoppy from '../src/utils/objCoppy'
Vue.prototype.$objCoppy = objCoppy
// 信息提示框
import myconfirm from '../src/utils/myconfirm'
Vue.prototype.$myconfirm = myconfirm
import * as filters from './filters' // global filters
// 按钮权限判断
import hasPermission from '@/permission/index'
Vue.prototype.hasPerm = hasPermission
import httpRspCode from '@/utils/rspCode'
Vue.prototype.httpRspCode = httpRspCode
// 组件通讯工具
Vue.prototype.$EventBus = new Vue()
/**
* If you don't want to use mock-server
* you want to use MockJs for mock api
* you can execute: mockXHR()
*
* Currently MockJs will be used in the production environment,
* please remove it before going online ! ! !
*/
// if (process.env.NODE_ENV === 'production') {
// const { mockXHR } = require('../mock')
// mockXHR()
// }
// 自定义组件
import MyComponents from '@/components'
Vue.use(MyComponents)
Vue.use(Element, {
size: Cookies.get('size') || 'medium' // set element-ui default size
// locale: enLang // 如果使用中文,无需设置,请删除
})
// register global utility filters
Object.keys(filters).forEach(key => {
Vue.filter(key, filters[key])
})
Vue.config.productionTip = false
// 新增:用于保存vue实例
let instance = null;
// 新增:动态设置 webpack publicPath,防止资源加载出错
if (window.__POWERED_BY_QIANKUN__) {
// eslint-disable-next-line no-undef
__webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}
/** * 新增: * 渲染函数 * 两种情况:主应用生命周期钩子中运行 / 微应用单独启动时运行 */
function render(props = {}) {
console.log(props)
const { container,onGlobalStateChange } = props;
if(onGlobalStateChange){
setTimeout(()=>{
props.bus.$emit('setBusToken','456')
props.setGlobalState({ token: 'microActionToken' })
console.log(123)
},5000)
props.onGlobalStateChange((state, prevState) => {
// state: 变更后的状态; prev 变更前的状态
state.path ? router.push(state.path) : ''
console.log('通信状态发生改变:', state, prevState);
// 这里监听到globalToken变化再更新store
// store.commit('setToken', '******')
}, true);
}
// 挂载应用
instance = new Vue({
router,
store,
render: (h) => h(App),
}).$mount(container ? container.querySelector('#micro-app-child') : '#micro-app-child');
}
/**
* 新增:
* bootstrap 只会在微应用初始化的时候调用一次,
下次微应用重新进入时会直接调用 mount 钩子,不会再重复触发 bootstrap。
* 通常我们可以在这里做一些全局变量的初始化,比如不会在 unmount 阶段被销毁的应用级别的缓存等。
*/
export async function bootstrap() {
console.log("VueMicroApp bootstraped");
}
/**
* 新增:
* 应用每次进入都会调用 mount 方法,通常我们在这里触发应用的渲染方法
*/
export async function mount(props) {
console.log("VueMicroApp mount22", props);
setTimeout(()=>{
props.setGlobalState({ name: '基站' });
},2000)
render(props);
}
/**
* 新增:
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount() {
console.log("VueMicroApp unmount");
instance.$destroy();
instance = null;
}
// 新增:独立运行时,直接挂载应用
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
// new Vue({
// el: '#app',
// router,
// store,
// render: h => h(App)
// })
第二种方式的好处是,基站和微服务可以设置同一个store,然后直接替换,微服务想要改变值的时候不需要判断是不是单独启动的,直接改变即可,使用时根据各自的业务场景判断,
如需参考详细的,详细代码可参考:樊小书生的原创文章添加链接描述