前言:最近测试在项目微前端(micro-app)生产环境下发现了一个bug--el-table筛选框定位偏移,但是本地却复现不出来,经过一波折发现是微前端环境下的el-table的筛选框定位问题,所以记录一下。
bug如下
点击岗位的筛选框,筛选框定位偏移。
废话不多说直接出结论。
- 已知在
el-table
列中设置filtersfilter-method
属性即可开启该列的筛选效果如下。
- F12查看该列的筛选框,发现点击筛选列会在
body
下插入筛选框div,并相对父元素body
绝对定位。
注意:el-table的筛选框用的也是vue-popper,具体可以下载源码查看这里不做赘述。
重点来了...
- 在
micro-app
微前端环境下,该筛选框div的父元素为body下<micro-app-body>
标签,但是在定位时,top和left还是根据页面body来计算的,但是其相对定位的父元素却变成了<micro-app-body>
(内嵌子应用页面)从而导致筛选框向右下偏移。
解决方案
由于我没有更改微前端的权限,所以只能在子应用中去做适应。鄙人不才试了好多种方法都没生效,但是页面窗口变化时,筛选框会重新计算位置回复到正常位置。
于是我在点击表头进行筛选时,给页面窗口绑定resize事件,重新计算筛选框的位置。
//表头增加点击事件
@header-click="onHeaderClick"
...
...
//$nextTick()没用,所以写了个延时。
onHeaderClick(column) {
if (column.label == "xxx") {
setTimeout(() => {
window.dispatchEvent(new Event("resize"));
}, 30);
}
}
关于vue-popper
vue-popper在element ui有很多运用,其中el-table的筛选框也是基于vue-popper实现的。其定位方式有两种
- 方案一: append-to-body 式。此模式下,弹出层会被放在 元素上,通过 position:fixed 定位,配合动态的 top 和 left 属性,完成弹出元素的定位。
- 方案二: 非 append-to-body 式。此模式下,弹出层通过 position:absolute 定位,配合其父元素 position:relative 来完成弹出元素的定位。