Tencent / wujie

极致的微前端框架
https://wujie-micro.github.io/doc/
Other
3.9k stars 554 forks source link

【方案讨论】针对el中依赖了poper.js 的fixed定位偏移解决方案 #682

Open TheYuuu opened 10 months ago

TheYuuu commented 10 months ago

我这边是fork的qiankun自己在团队内增加特性功能,最近参考(缝)了wujie的一些方案后,也遇到了poper fixed定位偏移问题

解决思路如下,对body的append进行劫持,判断className是否有el-popper,有的话用MutationObserver监听style属性,有变化就把fixed改成abs,再处理好隐藏和删除逻辑,目前运行没有什么问题。

image
quqingfei commented 10 months ago

昨晚熬夜4个小时排查原因,以及使用最小代价实现弹框偏移解决办法:刚刚写了热乎的文章。可以参考一下。 微前端下element-ui弹框偏移问题解决 另外附上实现效果: GIF

wildTechnician commented 10 months ago

elmenet plus 依旧没有解决

yiludege commented 10 months ago

elmenet plus 依旧没有解决

将popper定位强制改成绝对定位可以解决吗

image
wildTechnician commented 10 months ago

elmenet plus 依旧没有解决

将popper定位强制改成绝对定位可以解决吗 image

这样可以诶。。。。。谢谢

LedoTao commented 10 months ago

昨晚熬夜4个小时排查原因,以及使用最小代价实现弹框偏移解决办法:刚刚写了热乎的文章。可以参考一下。 微前端下element-ui弹框偏移问题解决 另外附上实现效果: GIF

antd5.8的版本不生效

zqy233 commented 9 months ago

@quqingfei 解决了哥,666,感谢

ShihHsing commented 8 months ago

子应用内打开的 popover 的弹层,点击子应用内的非自身会关闭,但是点击基座应用的菜单,不会自动关闭

nigiwen commented 8 months ago

@quqingfei vxe-modal不生效啊哥们

kqq0825 commented 7 months ago

解决思路:把popper的dom直接塞进主应用的body中,判断定位和显示边界也直接以主应用作为左边起点,这样的效果就和正常在项目中使用appendToBody的效果一致,代码改动也非常的少。

因为公司内部使用的组件库是基于element-ui进行封装的,所以直接在源码上进行更改了。 如果不能直接修改element-ui的源码,明确修改代码位置后,可以使用js-loader或者项目build之前修改node_modules代码。 以下代码目录都是基于element-ui源码的目录,对应在node_modules中的地址是lib/utilssrc/utils/vue-popper

// 源码
this.appendToBody && document.body.appendChild(this.popperElm);
// 修改后
if (this.appendToBody) {
    if (window.__POWERED_BY_WUJIE__) {
      window.parent.document.body.appendChild(this.popperElm);
    } else {
      document.body.appendChild(this.popperElm);
    }
  }

src/utils/popper.js

// 源码
var root =  window;
// 修改后
var root = window.__POWERED_BY_WUJIE__ ? window.parent : window;
// 源码
function getStyleComputedProperty(element, property) {
      // NOTE: 1 DOM access here
      var css = root.getComputedStyle(element, null);
      return css[property];
  }
// 修改后
function getStyleComputedProperty(element, property) {
      // NOTE: 1 DOM access here
      // wujie环境下向上遍历offsetParent时 过滤document类型得节点,避免方法getComputedStyle报错
      if (window.__POWERED_BY_WUJIE__ && element.nodeType === 9) return 'static'; 
      var css = root.getComputedStyle(element, null);
      return css[property];
  }
yiludege commented 7 months ago

解决思路:把popper的dom直接塞进主应用的body中,判断定位和显示边界也直接以主应用作为左边起点,这样的效果就和正常在项目中使用appendToBody的效果一致,代码改动也非常的少。

因为公司内部使用的组件库是基于element-ui进行封装的,所以直接在源码上进行更改了。 如果不能直接修改element-ui的源码,明确修改代码位置后,可以使用js-loader或者项目build之前修改node_modules代码。 以下代码目录都是基于element-ui源码的目录,对应在node_modules中的地址是lib/utilssrc/utils/vue-popper

// 源码
this.appendToBody && document.body.appendChild(this.popperElm);
// 修改后
if (this.appendToBody) {
    if (window.__POWERED_BY_WUJIE__) {
      window.parent.document.body.appendChild(this.popperElm);
    } else {
      document.body.appendChild(this.popperElm);
    }
  }

src/utils/popper.js

// 源码
var root =  window;
// 修改后
var root = window.__POWERED_BY_WUJIE__ ? window.parent : window;
// 源码
function getStyleComputedProperty(element, property) {
      // NOTE: 1 DOM access here
      var css = root.getComputedStyle(element, null);
      return css[property];
  }
// 修改后
function getStyleComputedProperty(element, property) {
      // NOTE: 1 DOM access here
      // wujie环境下向上遍历offsetParent时 过滤document类型得节点,避免方法getComputedStyle报错
      if (window.__POWERED_BY_WUJIE__ && element.nodeType === 9) return 'static'; 
      var css = root.getComputedStyle(element, null);
      return css[property];
  }

不错的思路,无界把整个子应用dom都塞到shadowdom了,递归body的时候到了子应用的body就停止了,你这个从源头解决了,可以贡献一个 plugin,不过不同组件库appendToBody的代码可能不太一致,压缩后代码还需要自己找出来做替换了

Maple01 commented 6 months ago

@quqingfei 学习了,感谢

hoganjobs commented 3 months ago

子应用内打开的 popover 的弹层,点击子应用内的非自身会关闭,但是点击基座应用的菜单,不会自动关闭

这个问题有解决的吗?

Mart0119 commented 2 months ago

.el-popper, .el-tooltip__popper { position: absolute !important; } 可以解决 子应用 弹出层&tooltip 定位问题