使用wujie微前端,主子应用都是vue+vite:实现localStorage隔离,解决子应用使用vite时样式丢失问题,解决子应用element-plus悬浮组件(日期框、下拉框)计算偏移量错误

主应用安装wujie

wujie有专门封装vue、react的组件,直接安装组件使用,这里主应用vue2,vue3的话安装wujie-vue3

npm i -s wujie-vue2

main.js

import WujieVue from 'wujie-vue2';
Vue.use(WujieVue);

主体布局中使用全局组件
currentRouterName是子应用的url地址,我的项目中是在应用列表页面中,点击应用打开新页面时获取和设置该变量。这个变量需要根据个人项目来实现,所以不贴出具体的代码。
showWuJie是判断是嵌入的子应用页面时才进行显示,有一些是主应用中的页面,这些页面不走wujie。这个变量需要根据个人项目来实现,所以不贴出具体的代码。
plugins是对子应用直接进行一些改造,且不需要去子应用中修改。
props是传递给子应用的参数

 <WujieVue
        height="100%"
        name="vue2"
        :url="currentRouterName"
        :plugins="plugins"
        v-show="showWuJie"
        :props="{ userInfo, token }"></WujieVue>

使用插件解决问题:一、解决子应用使用vite时样式丢失问题;二、解决子应用组件库element-plus悬浮组件(日期框、下拉框)计算偏移量错误问题

data中定义

 plugins: [
        {
    
    
          // 解决子应用使用vite时样式丢失问题 
          // https://github.com/Tencent/wujie/issues/434#issuecomment-1614089196
          patchElementHook(element, iframeWindow) {
    
    
            if (element.nodeName === 'STYLE') {
    
    
              element.insertAdjacentElement = function (_position, ele) {
    
    
                iframeWindow.document.head.appendChild(ele);
              };
            }
          },
        },
        {
    
    
          // 在子应用所有的css之前,为子应用插入样式
          cssBeforeLoaders: [
            // 强制使子应用body定位是relative
            {
    
     content: 'body{position: relative !important}' },
            // 解决子应用高度问题
            {
    
     content: 'html{height: 100%}' },
            {
    
     content: 'body{height: 100%}' },
            {
    
     content: '#app{height: 100%}' },
          ],
        },
        {
    
    
          // 解决子应用计算偏移量错误问题
          jsLoader: (code) => {
    
    
            // 替换popper.js内计算偏左侧偏移量
            var codes = code.replace(
              'left: elementRect.left - parentRect.left',
              'left: fixed ? elementRect.left : elementRect.left - parentRect.left'
            );
            // 替换popper.js内右侧偏移量
            return codes.replace(
              'popper.right > data.boundaries.right',
              'false'
            );
          },
        },
      ],

解决主子应用localStorage隔离问题

在主应用中重写localStorage函数,为localStorage加入前缀,因为主子应用共用的都是主应用的window,主应用中调用一下即可
这里我取得是window.location.pathname,根据个人需求自行更改

    // 隔离localstorage
    const originalSetItem = window.localStorage.setItem;
    const originalGetItem = window.localStorage.getItem;
    // 不需要添加前缀的白名单存储键
    const whiteStorage = ['core_platform_user_information'];
    window.localStorage.setItem = function (key, value) {
    
    
      originalSetItem.call(
        window.localStorage,
        whiteStorage.includes(key) ? key : window.location.pathname + '_' + key,
        value
      );
    };
    window.localStorage.getItem = function (key) {
    
    
      return originalGetItem.call(
        window.localStorage,
        whiteStorage.includes(key) ? key : window.location.pathname + '_' + key
      );
    };
    window.localStorage.clear = function () {
    
    
      for (let i = 0; i < localStorage.length; i++) {
    
    
        const key = localStorage.key(i);
        if (
          key.startsWith(window.location.pathname) ||
          whiteStorage.includes(key)
        ) {
    
    
          localStorage.removeItem(key);
        }
      }
    };

需要共享给子应用的数据使用wujie的props传参

子应用接收传参,然后自己存起来

 created() {
    
    
    // 父应用props传参
    localStorage.setItem(
      'core_platform_user_information',
      JSON.stringify(window.$wujie?.props?.userInfo)
    );
    localStorage.setItem('token', window.$wujie?.props?.token);
    console.log('子应用获取父应用通信传参', window.$wujie?.props?.userInfo, window.$wujie?.props?.token);
  },

猜你喜欢

转载自blog.csdn.net/qq_42611074/article/details/138208306