关于乾坤的样式隔离带来的问题
关于乾坤的样式隔离 experimentalStyleIsolation
,网上一搜都有好多,例如:
其实引入一个配置去解决问题,可能会引入新的问题,但是问题能否解决,也取决于使用工具的人。
我整体的看了一下网上说的“坑”,其实就是组件的一些弹窗默认是挂载到 body
上的,这就导致了再使用微前端集成的时候,子应用的弹窗逃逸,导致无法控制其弹窗的样式。
找到根本的原因,其实就好解决了。
在乾坤出现之前,饿了么组件就已经用的很多了,但是当时的组件设计师们,也没有考虑到后续会有这种微前端集成的需求,再加上现在组件维护不及时,所以就导致现在网上流行说的这些坑。例如 antd
下通过 ConfigProvider getPopupContainer
指定弹框渲染的范围,这样就解决了上面说的逃逸问题。
我这里抛个砖,大家可以看看目前这种设计方案的可行性,先上代码:
Vue.prototype.$ELEMENT = {
size: opts.size || '',
zIndex: opts.zIndex || 2000
content: opts.content || ''
};
先给组件全局配置一个 content
属性,接受需要挂载容器的 ID
然后利用计算属性,获取全局挂载容器,然后把默认的 document.body
替换成全局的挂载容器就可以简单的实现。
整体修改代码可以看这里:https://github.com/ElemeFE/element/pull/22666
使用的时候只需要配置
Vue.use(Element, { content: 'content' });
再根节点设置下挂载容器:
<template>
<div id="app">
<!-- 原来的逻辑 -->
...
<!-- 挂载容器,如果忘记,会自动挂载到 body 中 -->
<div id="content"></div>
</div>
</template>
前后配置应该不超过5分钟,就可以完成了,看下最后的效果图:
里面的浮窗和弹窗都挂载到了 content
中。
其实网上还有其他的解决方案:
- 不开启样式隔离,通过配置替换
el
前缀来达到目前,但是这种方案其实只能解决主子应用组件间的样式冲突,如果主子应用有相同的类名还是会有样式冲突,治标不治本。 - 重写了子应用的
document.body.appendChild
,让dialog挂载到子应用的节点中,如果有多应用保活,重写后的appendChild
会导致其他子应用也挂载到重写的那个子应用中,导致其他子应用出现dialog
消失的问题。
目前饿了么官方还没有合并文中修改的代码,也希望有更好的方案能够解决这种子应用逃逸的问题。如果想试用我维护的饿了么组件,也可以移步到这里查看。