前言
昨天写了一篇 JavaScript 小数精度遇到的坑 (传送门),今天又写一篇填坑心得,别问我为什么,坑就是这么多。不过话说回来,Element-UI 的 BUG 是真的有点多啊,特别是 1.x 版本,然而由于历史原因,我们项目还在用 1.x 版本😐😐😐。
发现问题
现在开始进入正题,说下如何入坑的,有2个标签页,每个标签页下面有一个表格展示数据,可以切换顶部的标签来切换显示哪一个表格。用 el-tabs
和 el-table
两个组件嵌套就可以搞定,没什么问题😊。可是测试的时候发现一个问题,当重新加载数据时,隐藏的那个标签页下面的表格 body
部分高度不知为啥消失了。用调试工具查看元素时,发现表格 .el-table__body-wrapper
这个元素有个内联样式 height: 1px
,这一看就是 Element-UI 框架计算出来的高度,于是就向这个方向去排查。
如何解决?
既然有了方向,那么该如何解决呢?当然是去看源码了,我是自己在本地的 node_modules 目录下面看的,就在 /node_modules/element-ui/packages/table
这个文件夹下面,然后看 index.js
里面引用的是 'src/table'
,那就从 src/table.vue
(源码传送门) 这个组件开始看吧。
由于之前已经发现了 .el-table__body-wrapper
这个元素的内联样式计算有问题,所以直接找到 <template>
的这个元素,发现果然有个动态绑定的样式 bodyHeight
,这是一个 Vue
的计算属性 bodyHeight
(源码传送门)。简单的分析之后,发现高度的计算都与 this.layout
这个对象相关,于是,我将目标转到 this.layout
上面。
继续分析 this.layout
,这是由 TableLayout
类 (源码传送门) 实例化出来的一个对象。再结合之前计算高度的地方引用了 this.layout.bodyHeight
,所以直接搜索 bodyHeight
,发现都在这个类的 updateHeight
方法里。大致看了下这个方法的代码,就是通过获取一些元素的高度,进行一些计算的操作(说了跟没说一样😏),反正看不出来有什么问题。
所以,该怎么办?
好像碰到瓶颈了,该怎么办?我的第一个想法就是断点调试呗,这是在 node_modules 目录下的,怎么断点?我的解决办法就是继承 el-table
组件,然后在 Vue 生命周期的 created
方法里面覆盖 this.layout
的值,代码如下:
1 | // my-table.js |
然后在将 my-table.js 引入作为 Vue 组件,将 el-table
替换成 my-table
。到这里,已经成功在刚才的方法里打上了一个断点。
切换到之前出 BUG 的场景,成功进入断点,单行调试。发现组件的高度为 0px,再仔细一看,竟然是 .el-tab-pan
这个元素 display: none
,它的子元素肯定获取不到高度啊。而这个元素隐藏应该是 el-tabs
组件切换标签页造成的。很明显锅不在 el-table
,而在 el-tabs
啊👀。
那就看 el-tabs
组件的源码吧 (源码传送门),看到 .el-tab-pane
这个元素的显隐是通过 v-show="active"
控制的,而 active
是一个 Vue 的计算属性,就是判断当前的面板是否处于激活状态。到这里,我们终于知道了这BUG产生的原因了。
所以,然后呢?
Element-UI 的 el-tabs
组件是通过 v-show
来控制标签页的显隐,这非常简单暴力,但同时也导致了我们刚开始说的计算高度失效这个问题。所以,我们可以就让所有的标签页下的内容都“显示”出来,然后通过 z-index
来控制显隐,注意背景不要透明(当然也有其他实现方式,只要能获取到表格的真实高度就行)。直接改写 el-tab-pane
组件,代码如下:
template 部分:
1 | <template> |
这里把 v-show 换成绑定一个动态样式,用于动态设置 z-index
script 部分:
1 | export default { |
这里在计算属性这里添加了一个 paneStyle
,用于动态设置面板的样式,激活状态 z-index 设置为1,其他情况设置为0,相当于激活状态的面板总是在顶层。
style 部分 (scss)
1 | .el-tabs .el-tabs__content { |
这里由于 .el-tabs__content
之前被重写为 flex 布局,所以这里重新改成 block,然后把 .el-tab-pane
改成绝对定位,收工👌。别忘了把 el-tab-pane
换成重写之后的。
来点感想
首先,element-ui的坑有点多,相信每个框架都有各种坑,我们踩坑的过程其实就是给自己涨经验。所以,不要怕踩坑。还有一点我想说的就是,不要怕看源码,源码没有想象的那么可怕。多看看源码可以对自己的提升肯定是有好处的(好像又是一句废话😏)。
1 | ┏┓ ┏┓+ + |