qiankun-微前端初次使用并体验

主项目以及子项目都是VUE项目,两个项目路由:都为history

主应用引入qiankun 插件

安装qiankun

$ yarn add qiankun # 或者 npm i qiankun -S

在主应用当中注册微应用

//接入微服务
import { registerMicroApps, start } from 'qiankun';
new Vue({
  router,
  store,
  i18n,
  created: bootstrap,
  render: h => h(App)
}).$mount('#app')
registerMicroApps([
  {
    name: 'qiankun-children',
    entry: '//localhost:8081',
    container: '#yourContainer',
    activeRule: '/dome1',
    sandbox: {
      strictStyleIsolation: true
    },
  },
]);
if (!window.qiankunStarted) {
  window.qiankunStarted = true;
    start();
}
vue.config.js 
  devServer: {
    port: 8008,
    headers: {  //配置需要添加跨域访问配置
      'Access-Control-Allow-Origin': '*',
    },
    overlay: {
      warning: false,
      errors: false
    }
  },

子应用注册

代码如下:


let instance = null;
function render(props = {}) {
	console.log(props)
  const { container } = props;
  instance = new Vue({
      router,
      store,
      i18n,
    render: (h) => h(App),
  }).$mount(container ? container.querySelector('#app') : '#app');
}
if(__webpack_public_path__){
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;

}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}
if(window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__){
  console.log(window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__,window,"--") ;
}

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;
}

在启动以及打包、编辑可能遇到的问题
如下:

启动之后刷新页面子应用会消失

这是因为主应用和子应用两个id不能同时加载,需要异步处理子应用加载id的时间


if (!window.qiankunStarted) {
  window.qiankunStarted = true;
  setTimeout(()=>{
    start();
  },2000)
}

接入路由之后点击路由切换会出现问题

解决办法如下:

在子应用里面添加public-path.js

代码如下:

if (window.__POWERED_BY_QIANKUN__) {
    // eslint-disable-next-line no-undef
    __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;
}

在子路由配置router添加前缀

export default new Router({
  mode: 'history',
  base: window.__POWERED_BY_QIANKUN__ ? '/dome1' : '/',
  routes: asyncRouterMap
})

在打包的时候会出现子应用$router找不到的问题。

在这里插入图片描述
qiankun 中的代码使用 Proxy 去代理父页面的 window,来实现的沙箱,在微应用中访问 window.Vue 时,会先在自己的 window 里查找有没有 Vue 属性,如果没有就去父应用里查找。

在 VueRouter 的代码里有这样三行代码,会在模块加载的时候就访问 window.Vue 这个变量,微应用中报这个错,一般是由于父应用中的 Vue 挂载到了父应用的 window 对象上了。

解决办法如下:

标题在主应用main.js添加如下代码**

window.Vue2=window.Vue
delete window.Vue

打包之后样式隔离问题,如何确保主应用跟微应用之间的样式隔离

通过配置 { sandbox : { experimentalStyleIsolation: true } } 的方式开启运行时的 scoped css 功能,从而解决应用间的样式隔离问题。
解决办法如下:

registerMicroApps([
  {
    name: 'qiankun-children',
    entry: '//localhost:8081',
    container: '#yourContainer',
    activeRule: '/dome1',
    sandbox: {
      strictStyleIsolation: true  //主应用添加隔离属性
    },
  },
]);

整体主应用代码

// with polyfills
import 'core-js/stable'
import 'regenerator-runtime/runtime'
import VueCodeMirror from 'vue-codemirror'
import 'codemirror/lib/codemirror.css'
import Vue from 'vue'
import App from './App.vue'
import {router} from './router'
import store from './store/'
import i18n from './locales'
import { VueAxios } from './utils/request'
import ProLayout, { PageHeaderWrapper } from '@ant-design-vue/pro-layout'
import themePluginConfig from '../config/themePluginConfig'
import { mixins } from '@/utils/mixins'

//接入微服务
import { registerMicroApps, start } from 'qiankun';
// 以下为bpmn工作流绘图工具的样式
import 'bpmn-js/dist/assets/diagram-js.css' // 左边工具栏以及编辑节点的样式
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-codes.css'
import 'bpmn-js/dist/assets/bpmn-font/css/bpmn-embedded.css'
import 'bpmn-js-properties-panel/dist/assets/bpmn-js-properties-panel.css' // 右边工具栏样式
// 图数据预览
import {vuePlugin}  from "@/highlight";
import "highlight.js/styles/atom-one-dark-reasonable.css";
Vue.use(vuePlugin);

Vue.mixin(mixins)

import MagicContextMenu from './components/common/magic-contextmenu'
import Modal from './components/common/modal'
Vue.config.productionTip = false

Vue.use(MagicContextMenu)
Vue.use(Modal)
// mock
// WARNING: `mockjs` NOT SUPPORT `IE` PLEASE DO NOT USE IN `production` ENV.
// import './mock'

import bootstrap from './core/bootstrap'
import './core/lazy_use'
import './permission' // permission control
import './utils/filter' // global filter
import './global.less'
import './globalTheme.less'
//JSON展示插件
import JsonViewer from 'vue-json-viewer'
import 'vue-json-viewer/style.css'
Vue.use(JsonViewer)

//高亮显示代码编辑插件
import { codemirror } from 'vue-codemirror'
import 'codemirror/lib/codemirror.css'
Vue.use(codemirror)
//XML转换JSON插件
import x2js from 'x2js'
Vue.prototype.$x2js = new x2js()
//复制到粘贴板插件 VueClipboard该变量代码里搜不到 使用中 误删!
import VueClipboard from 'vue-clipboard2'
VueClipboard.config.autoSetContainer = true
Vue.use(VueClipboard)
//颜色选择器
import vcolorpicker from 'vcolorpicker'

//表格插件
import 'xe-utils'
import VXETable from 'vxe-table'
import 'vxe-table/lib/index.css'
import VXETablePluginAntd from 'vxe-table-plugin-antd'
import 'vxe-table-plugin-antd/dist/style.css'
Vue.use(VXETable)
VXETable.use(VXETablePluginAntd) //插件兼容ant-design-vue 配置

Vue.config.productionTip = false

// mount axios to `Vue.$http` and `this.$http`
Vue.use(VueCodeMirror)
Vue.use(vcolorpicker)
Vue.use(VueAxios)
Vue.component('pro-layout', ProLayout)
Vue.component('page-header-wrapper', PageHeaderWrapper)

window.umi_plugin_ant_themeVar = themePluginConfig.theme
window.Vue2=window.Vue
delete window.Vue
new Vue({
  router,
  store,
  i18n,
  created: bootstrap,
  render: h => h(App)
}).$mount('#app')
registerMicroApps([
  {
    name: 'qiankun-children',
    entry: '//localhost:8081',
    container: '#yourContainer',
    activeRule: '/dome1',
    sandbox: {
      strictStyleIsolation: true
    },
  },
]);

if (!window.qiankunStarted) {
  window.qiankunStarted = true;
  setTimeout(()=>{
    start();
  },2000)
}

子应用代码

// with polyfills
import './public-path'
import 'core-js/stable'
import 'regenerator-runtime/runtime'

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store/'
import i18n from './locales'
import { VueAxios } from './utils/request'
import ProLayout, { PageHeaderWrapper } from '@ant-design-vue/pro-layout'
import themePluginConfig from '../config/themePluginConfig'

// mock
// WARNING: `mockjs` NOT SUPPORT `IE` PLEASE DO NOT USE IN `production` ENV.
// import './mock'

// import bootstrap from './core/bootstrap'
import './core/lazy_use' // use lazy load components
import './permission' // permission control
import './utils/filter' // global filter
import './global.less' // global style

Vue.config.productionTip = false
import 'xe-utils'
import VXETable from 'vxe-table'
import 'vxe-table/lib/style.css'

Vue.use(VXETable)
// mount axios to `Vue.$http` and `this.$http`
Vue.use(VueAxios)
// use pro-layout components
Vue.component('pro-layout', ProLayout)
Vue.component('page-container', PageHeaderWrapper)
Vue.component('page-header-wrapper', PageHeaderWrapper)

window.umi_plugin_ant_themeVar = themePluginConfig.theme

// new Vue({
//   router,
//   store,
//   i18n,
//   // init localstorage, vuex, Logo message
//   created: bootstrap,
//   render: h => h(App)
// }).$mount('#app')


let instance = null;
function render(props = {}) {
	console.log(props)
  const { container } = props;
  instance = new Vue({
      router,
      store,
      i18n,
    render: (h) => h(App),
  }).$mount(container ? container.querySelector('#app') : '#app');
}
if(__webpack_public_path__){
  __webpack_public_path__ = window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__;

}
// 独立运行时
if (!window.__POWERED_BY_QIANKUN__) {
  render();
}
if(window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__){
  console.log(window.__INJECTED_PUBLIC_PATH_BY_QIANKUN__,window,"--") ;
}

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;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Shero.李建业

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值