关于乾坤的样式隔离带来的问题

关于乾坤的样式隔离 experimentalStyleIsolation,网上一搜都有好多,例如:

2023-09-12T01:29:03.png

其实引入一个配置去解决问题,可能会引入新的问题,但是问题能否解决,也取决于使用工具的人。

我整体的看了一下网上说的“坑”,其实就是组件的一些弹窗默认是挂载到 body 上的,这就导致了再使用微前端集成的时候,子应用的弹窗逃逸,导致无法控制其弹窗的样式。

2023-09-12T01:35:24.png

找到根本的原因,其实就好解决了。

在乾坤出现之前,饿了么组件就已经用的很多了,但是当时的组件设计师们,也没有考虑到后续会有这种微前端集成的需求,再加上现在组件维护不及时,所以就导致现在网上流行说的这些坑。例如 antd 下通过 ConfigProvider getPopupContainer 指定弹框渲染的范围,这样就解决了上面说的逃逸问题。

我这里抛个砖,大家可以看看目前这种设计方案的可行性,先上代码:

Vue.prototype.$ELEMENT = {
  size: opts.size || '',
  zIndex: opts.zIndex || 2000
  content: opts.content || ''
};

先给组件全局配置一个 content 属性,接受需要挂载容器的 ID

然后利用计算属性,获取全局挂载容器,然后把默认的 document.body 替换成全局的挂载容器就可以简单的实现。

2023-09-12T01:40:52.png

整体修改代码可以看这里:https://github.com/ElemeFE/element/pull/22666

使用的时候只需要配置

Vue.use(Element, { content: 'content' });

再根节点设置下挂载容器:

<template>
  <div id="app">
    <!-- 原来的逻辑 -->
    ...
    <!-- 挂载容器,如果忘记,会自动挂载到 body 中 -->
    <div id="content"></div>
  </div>
</template>

前后配置应该不超过5分钟,就可以完成了,看下最后的效果图:

2023-09-12T01:42:16.png

2023-09-12T01:42:27.png

里面的浮窗和弹窗都挂载到了 content 中。

其实网上还有其他的解决方案:

  1. 不开启样式隔离,通过配置替换 el 前缀来达到目前,但是这种方案其实只能解决主子应用组件间的样式冲突,如果主子应用有相同的类名还是会有样式冲突,治标不治本。
  2. 重写了子应用的 document.body.appendChild,让dialog挂载到子应用的节点中,如果有多应用保活,重写后的appendChild会导致其他子应用也挂载到重写的那个子应用中,导致其他子应用出现dialog消失的问题。

目前饿了么官方还没有合并文中修改的代码,也希望有更好的方案能够解决这种子应用逃逸的问题。如果想试用我维护的饿了么组件,也可以移步到这里查看

添加新评论