35.4.qiankun应用案例

1.父级组件
utils文件下

import store from "../store";
import {toLogin} from "./login";
/**
 * @name 导入注册并启动微应用函数
 */

/**
 * @name 声明一个常量准备将props内的部分内容储存起来
 */
const STORE = {};

/**
 * @name 启动qiankun应用间通信机制
 * @param {Function} initGlobalState 官方通信函数
 * @description 注意:主应用是从qiankun中导出的initGlobalState方法,
 * @description 注意:子应用是附加在props上的onGlobalStateChange, setGlobalState方法(只用主应用注册了通信才会有)
 */
const appStore = (initGlobalState) => {
  /**
   * @name 初始化数据内容
   */
  const {onGlobalStateChange, setGlobalState} = initGlobalState({
    ignore: '',
    msg: '',
    logout: false,
    currentName: '',
    isAdmin: false,
    isshowLeftNav: false
  });

  /**
   * @name 监听数据变动
   * @param {Function} 监听到数据发生改变后的回调函数
   * @des 将监听到的数据存入vuex
   */
  onGlobalStateChange((value, prev) => {
    console.log('[onGlobalStateChange - main]:', value, prev);
    //测试数据同步
    'msg' in value
    && store.dispatch('appstore/setMsg', value.msg)
    // 角色名称
    value.currentName && store.dispatch('user/updateStates', {
      currentName: value.currentName
    })

    // 调回到管理后台
    !value.isAdmin && store.dispatch('menu/updateStates', {isAdmin: false})
    !value.isshowLeftNav && store.dispatch('menu/updateStates', {isshowLeftNav: false})

    // 某个程序登录token 过期
    value.logout &&  toLogin()
    // value.token && store.dispatch('app/setToken', value.token);
    // value.appsRefresh && window?.location?.reload?.();
  });

  /**
   * @name 改变数据并向所有应用广播
   */
  setGlobalState({
    ignore: 'main',
    // msg: '来自master动态设定的消息'
  });

  /**
   * @name 将你需要的数据存起来,供下面setState方法使用
   */
  STORE.setGlobalState = setGlobalState;
  STORE.name = 'main';
}

function isObject(val) {
  return Object.prototype.toString.call(val) === "[object Object]";
}

/**
 * @name 全局setState方法,修改的内容将通知所有微应用
 * @param {Object} data 按照你设定的内容格式数据
 */
const setState = (data) => {
  if (!isObject(data)) {
    throw Error('data必须是对象格式');
  }
  STORE.setGlobalState?.({
    ignore: 'main',
    ...data
  })
}

export {
  setState
}

export default appStore;

2.main文件引入

import Vue from 'vue'
import store from './store'
import App from './App.vue'
import router from './router'
import sso from '@oppo/helper-sso'
import VueLoading from 'vue-loading-template'
// qiankun
import {registerMicroApps, start, initGlobalState} from 'qiankun';

window.__POWERED_BY_QIANKUN_PARENT__ = true
// initGlobalState 配置
import appStore from "./utils/app-store";
Vue.prototype.bus = new Vue();
Vue.use(VueLoading, /** options **/)

// 统一样式引入
router.afterEach((to, from, next) => { // 默认滚动到顶部
  window.scrollTo(0, 0);
});
// const getComputedStyle = window.getComputedStyle;
// window.getComputedStyle = (el, ...args) => {
//   // 如果为shadow dom则直接返回
//   if (el instanceof DocumentFragment) {
//     return {};
//   }
//   return Reflect.apply(getComputedStyle, window, [el, ...args]);
// };

// 根据坐标(x, y)当获取一个子应用的元素的时候,会返回shadow root,并不会返回真正的元素
// const elementFromPoint = document.elementFromPoint;
// document.elementFromPoint = function (x, y) {
//   const result = Reflect.apply(elementFromPoint, this, [x, y]);
//   // 如果坐标元素为shadow则用该shadow再次获取
//   if (result && result.shadowRoot) {
//     return result.shadowRoot.elementFromPoint(x, y);
//   }
//   return result;
// };


// fix: 点击事件target为shadow元素的问题
// const {addEventListener: oldAddEventListener, removeEventListener: oldRemoveEventListener} = document;
// const fixEvents = ['click', 'mousedown', 'mouseup'];
// const overrideEventFnMap = {};
// const setOverrideEvent = (eventName, fn, overrideFn) => {
//   if (fn === overrideFn) {
//     return;
//   }
//   if (!overrideEventFnMap[eventName]) {
//     overrideEventFnMap[eventName] = new Map();
//   }
//   overrideEventFnMap[eventName].set(fn, overrideFn);
// };
// const resetOverrideEvent = (eventName, fn) => {
//   const eventFn = overrideEventFnMap[eventName]?.get(fn);
//   if (eventFn) {
//     overrideEventFnMap[eventName].delete(fn);
//   }
//   return eventFn || fn;
// };
// document.addEventListener = (event, fn, options) => {
//   const callback = (e) => {
//     // 当前事件对象为qiankun盒子,并且当前对象有shadowRoot元素,则fix事件对象为真实元素
//     if (e.target.id?.startsWith('__qiankun_microapp_wrapper') && e.target?.shadowRoot) {
//       fn({...e, target: e.path[0]});
//       return;
//     }
//     fn(e);
//   };
//   const eventFn = fixEvents.includes(event) ? callback : fn;
//   setOverrideEvent(event, fn, eventFn);
//   Reflect.apply(oldAddEventListener, document, [event, eventFn, options]);
// };
// document.removeEventListener = (event, fn, options) => {
//   const eventFn = resetOverrideEvent(event, fn);
//   Reflect.apply(oldRemoveEventListener, document, [event, eventFn, options]);
// };


registerMicroApps([
  //管理后台
  {
    name: 'admin',
    entry: `${process.env.VUE_APP_QIANKUN_URL}`, //  VUE_APP_QIANKUN_URL="//abc-admin-test.myoas.com"
    container: '#container',
    activeRule: '/admin',
    props: {
      data: store,

    }
  }
], {
  beforeLoad: app => {
    console.log('[主应用]before load app.name====>>>>>', app.name)
    store.commit('appstore/setPageLoading', true)
  },
  beforeMount: [
    app => {
      store.dispatch('menu/updateStates', {appName: app.name})
      console.log('[主应用][LifeCycle] before mount %c%s', 'color: green;', app.name);
    },
  ],
  afterMount: [
    app => {
      store.commit('appstore/setPageLoading', false)
      app.name === 'admin' ? localStorage.setItem('admin', true): ''
      app.name === 'admin' ? store.dispatch('menu/updateStates', {isAdmin: true}): ''
      localStorage.getItem('admin') === 'true' ? store.dispatch('menu/updateStates', {isAdmin: true}) : ''
      console.log('[主应用][LifeCycle] after mount %c%s', 'color: green;', app.name);
    }
  ],
  afterUnmount: [
    app => {
      console.log('[主应用][LifeCycle] after unmount %c%s', 'color: green;', app.name);
    },
  ],
});


// qiankun配置
start({
  prefetch: true, //预加载
  sandbox: {
    // strictStyleIsolation: true, // 样式沙箱开启
    experimentalStyleIsolation: true,
  }
})

// 开启 initGlobalState
appStore(initGlobalState)

new Vue({
  router,
  store,
  sso,
  render: h => h(App)
}).$mount('#app')
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值