主应用安装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);
},