前言
这两天碰到了一个bug,与el-table-column中show-overflow-tooltip属性有关,本节就来看一下具体的解决过程。
show-overflow-tooltip
show-overflow-tooltip是el-table-column的一个属性,该属性的属性值是个布尔值,默认为false,如果设置为true时,单元格内容过长时,就会变成el-tooltip的效果。
项目中运用了此属性,碰到了一个bug:当我们鼠标移动上去展示内容时,如果列表数据发生改变,此时浮动框的内容不会跟着变化,只有重新移开移入才会进行变化,为了解决这个问题,我们先来看下源码中show-overflow-tooltip的实现。
源码
项目中用的是element ui,打开gitlab源码,在table-column.js找到showOverflowTooltip属性。
继续往下查找,会看到相关逻辑处理:当列表有这个属性,就会增加el-tooltip类名,并且修改列宽。我们先来看下el-tooltip,找到tale.scss文件在.cell类名下就能看到el-tooltip:
cell与el-tooltip实现的效果就是,单元格超出部分就会用省略号代替,这跟官方文档描述的效果刚好对应上。悬浮框内容展示出来的行为是鼠标移入,我们就找一下单元格是否有移入事件。在table-body.js文件中刚好有handleCellMouseEnter事件:
事件中会根据是否具有el-tooltip类名判断,满足条件就会展示tooltip。往下看我们就会发现tooltip的实现就是通过el-tooltip组件实现的。
函数中tooltip是$refs获取的,我们找一下ref名为tooltip的组件,就能看到el-tooltip:
到此我们就能总结出show-overflow-tooltip属性的实现过程:
- 根据属性值去添加el-tooltip类名,并且设置宽度,让溢出单元格的内容变成省略号。
- 单元格的mouseEnter事件会判断单元格是否有el-tooltip类名,如果有就会开启el-tooltip中的popper,让内容显示出来。
根据实现过程我们就能得出bug产生的原因,当数据变化时并没有触发handleCellMouseEnter事件。
解决
为了让弹出框内容实时进行更新,有以下几种思路:
- 修改key值。vue底层用了diff算法进行视图更新,里面会用到key属性进行组件的对比,key值一样整体就不会重新渲染。在el-table-column绑定一个可变key值,当单元格数据变化时,更新key值,结果不生效。对diff算法的理解有待提高。
- 替换poper内容。既然它不能自动更新,那我们就手动更新,获取悬浮框dom元素,在数据发生改变时将里面的内容进行替换。这个方法很麻烦局限性也大,只能当最后的手段了。
- el-tooltip组件。既然show-overflow-tooltip最终效果跟el-tooltip效果一致,那么我们就直接用default插槽将需要用到show-overflow-tooltip属性的列,用el-tooltip写一下,el-tooltip悬浮框内容就是content参数,content变化时,视图会跟着一起更新了。采用此方法成功解决问题。
上面三个是解析源码前的想法,解析源码后我们知道了bug产生原因,就能'对症下药',在列表数据修改时,将handleCellMouseEnter事件执行一次就行。
总结
以上就是对show-overflow-tooltip属性的探索,当我们阅读源码知道bug产生原因后,解决bug就会更加轻松。