vue使用qiankun框架心得和踩坑记录
**其他网站有很多如何引入,使用的案例,但是按部就班的做了还是有一些问题,因此来此在总结下:vue2x使用qiankun框架经历实现:1、父子组件相互跳转2、父-子传参,子接收3、子使用父的组件遇到问题:1、路由跳转不成功2、父子样式冲突3、this.$router.push跳转问题,改为window.history.pushState跳转后,除了第一次主跳子,第二次会跳转到错误页面问题解决**第
**其他网站有很多如何引入,使用的案例,但是按部就班的做了还是有一些问题,因此来此在总结下:
vue2x使用qiankun框架经历
实现:
1、父子组件相互跳转
2、父-子传参,子接收
3、子使用父的组件
遇到问题:
1、路由跳转不成功
2、父子样式冲突
3、this.$router.push跳转问题,改为window.history.pushState跳转后,除了第一次主跳子,第二次会跳转到错误页面问题解决
**
第一步 :安装 npm i qiankun -S
第二步:在主应用src目录下创建文件夹micros,俩个js文件 app.js 和 index.js.如图
app.js文件内容:
/**
app.js导出的是上面registerMicroApps的第一个参数,是一个对象数组,其中数组每个字段的作用如下:
(1)name:微应用的名称,后面改造微应用的时候一定要与这个name对应
(2)entry:微应用运行的域名加端口,我用的是本地8088端口
(3)container:启动微应用需要一个dom容器,里面就是这个dom容器的 id
(4)activeRule:触发启动微应用的规则,当检测到url中含有activeRule的值时,将启动微应用
当微应用信息注册完之后,一旦浏览器的 url 发生变化,便会自动触发 qiankun 的匹配逻辑,所有 activeRule 规则匹配上的微应用就会被插入到指定的 container 中,同时依次调用微应用暴露出的生命周期钩子。
**/
const apps = [
{
name: 'micro-app-order',
entry: '//localhost:9527',
container: '#order-container',
activeRule: '#/resourcesCore'
}
]
export default apps
index.js文件内容:
/**
这里用到了官方的几个api:
(1)registerMicroApps:包含两个参数,第一个参数是微应用的一些注册信息,第二个参数是全局的微应用生命周期钩子。:
(2)addGlobalUncaughtErrorHandler:全局的未捕获异常处理器,微应用发生报错的时候亦可以用这个api捕捉。
(3)start:我们用来启动qiankun的方法,包含一个参数,具体的参数用途不再详述。
以上详细的api请点击查看官网API文档:https://qiankun.umijs.org/zh/api
**/
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)
//主应用给微应用传值使用action
export { actions }
export default start
第三步:主应用入口文件里引入qiankun,并运行,我是因为主应用和微应用css冲突,所以打开了沙箱模式,入口文件其他内容可以不动
import start from '@/micros'
// 运行qiankun,打开沙箱隔离,不想使用沙箱,直接start()
start({
sandbox: { strictStyleIsolation: true }
})
第四步:配置微服务路由,
1、app.vue 页面,引入微服务容器,id为上面js里定义的名称,一定要对应上,也可以在其他地方写,但是main里面的start().也要放到指定的地方开启,不然找不到id会报错滴
<template>
<div id="app">
<!-- 新添加,微应用的容器 -->
<div id="order-container"></div>
<router-view />
</div>
</template>
2、layout组件,也就是第二个的获取其他页面填写跳转,
actions.setGlobalState是给微服务传值,设置全局变量window.history.pushState是官方推荐的跳转方式,不能使用this.$touter跳转,会出现主跳子,子跳主,主再跳子,跳不过去的问题。
<div @click="onclick(1)">集群管理</div>
<div @click="onclick(2)">资源管理</div>
//方法
onclick(value) {
if (value === 1) {
actions.setGlobalState({ path: '/resourcesCore/colonyManage', token: 121 })
this.routerGo('#/resourcesCore/colonyManage', '我喜爱的男明星')
} else {
// actions.setGlobalState({ path: '/resourcesCore/resourcesManage', token: 222, data: {}})
this.routerGo('#/resourcesCore/resourcesManage', '我喜爱的男明星')
}
},
routerGo(href = '/', title = null, stateObj = {}) {
console.log()
window.history.pushState(stateObj, title, href);
},
至此,主站配置完成,
微服务配置开始
第一步,入口文件引入乾坤生命周期
1、之前new Vue实列放到render函数里
因为第二次主跳子服务时候,页面并没有跳到指定的页面,但是路由已经变过来了,没有走子的全局拦截钩子,所以我进行了router.push的跳转。
// 新增:用于保存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__;
}
/** * 新增: * 渲染函数 * 两种情况:主应用生命周期钩子中运行 / 微应用单独启动时运行,
onGlobalStateChange监听全局变量
使用沙箱情况下,$mount写法
$mount(container ? container.querySelector('#micro-app-child') : '#micro-app-child')
不适用可以$mount('#micro-app-child')
*/
function render(props = {}) {
console.log(props)
const { container,onGlobalStateChange } = props;
if(onGlobalStateChange){
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);
render(props);
}
/**
* 新增:
* 应用每次 切出/卸载 会调用的方法,通常在这里我们会卸载微应用的应用实例
*/
export async function unmount() {
console.log("VueMicroApp unmount");
instance.$destroy();
instance = null;
}
// 新增:独立运行时,直接挂载应用
if (!window.__POWERED_BY_QIANKUN__) {
render();
}
第二步:public中的index.html里面的id改为micro-app-child,跟入口实例化的对应上
第三步:配置webpack,也就是config.js,
1、output对象加入
2、跨域 Access-Control-Allow-Origin:‘*’
devServer: {
hot: true, // 自动保存
port: port,
open: true,
overlay: {
warnings: false,
errors: true
},
before: require('./mock/mock-server.js'),
// 关闭主机检查,使微应用可以被 fetch
disableHostCheck: true,
headers: {
'Access-Control-Allow-Origin': '*'
}
},
configureWebpack: {
// provide the app's title in webpack's name field, so that
// it can be accessed in index.html to inject the correct title.
name: name,
resolve: {
alias: {
'@': resolve('src')
}
},
output: {
// 微应用的包名,这里与主应用中注册的微应用名称一致
library: "micro-app-order",
// 将你的 library 暴露为所有的模块定义下都可运行的方式
libraryTarget: "umd",
// 按需加载相关,设置为 webpackJsonp_MicroAppOrde 即可
jsonpFunction: `webpackJsonp_micro-app-order`,
},
},
第四步:微服务使用主站中的组件,
1、主站中的组件放到window上,微服务中判断调用
主站中
微服务中
调用
至此就结束了,微应用的路由地址一定要跟主应用中micros中app.js中的activeRule配置一致,这样主站才能识别你想去哪个微服务。切记切记
更多推荐
所有评论(0)