Element Plus大家应该都不陌生,用过 el-table
的伙伴更是多数,毕竟搞ToB业务 table
必不可少,但是真正翻看过源码的应该还是少数,有没有对其内部实现怀揣着一点点好奇呢?笔者就是因为怀揣着好奇,所以才走上了源码这条不归路,为了让大家不走不归路,马上分享源码解析!现在回想当时,那是一个月黑风高的夜晚…
起因
故事的起因是这样的,在这个月黑风高的夜晚里,我手贱地点开了 Element Plus 的 gayhub,在上面翻看着各种内容,无意间,一条非常诡异的 issue
引起了我的注意,于是我就点开了,于是这就一发不可收拾了~
关于这条 issue
是这样的:
- 使用
v-for
生成<el-table-column />
的table
,添加key
属性后无法改变columns
的顺序。
这里笔者简要介绍下问题表象:
如图所示,两个 table
都是通过 v-for
来完成 columns
的生成。
- 其中第一个
table
(黄色箭头)的v-for
遵循使用规范,给循环的项增加了key
属性。 - 其中第二个
table
(蓝色箭头)的循环中并没有添加key
属性。 - 有一个按钮,点击后会互换
columnsData
的 第一、第二条数据
现在笔者点击按钮后界面发生如下变化:
对比这上面两张图,很明显就能看出来点击按钮后,没有绑定 key
属性的 table
成功互换了“两列”的位置,而加上了 key
的 table
“表面上”并没有动静,还是维持了原本的顺序。
感兴趣的朋友可以通过在线调试: Playground 点进去自己玩一下~
好了,就是这么一个问题。不知道读到这里的朋友有没有在开发中遇到这样的问题呢?笔者自问了一下,为什么自己从来没有遇到这个问题呢???看来平时只要代码不规范,就不会有两行泪~此时此刻,我不由自主地掏出了下面这张图,原来图中的道理是真的,信不信由你!
走远了走远了,回到这个问题上来不妨先思考一下,对一个 v-for
列表的列表添加 key
本是最合理不过的事情了,为什么会导致 table
互换列失败呢?基于这一点的疑问,我们就要翻开它的源码了~当然,整个 table
的源码还是相对比较多的,而本文更多的是针对这个 issue ,以找到问题的根源为发起点去解析源码,不能尽善尽全还请多多见谅。
一、初识<el-table>
说起“初识”其实也不算“初识”,毕竟使用了这么久了,用这个组件来完成了很多业务需求,应该算是个最熟悉的陌生人吧!那现在我们就开始尝试更深入的了解这个老朋友吧。
1. 组成结构
虽然是看源码,但是一上来就堆代码就怕吓跑你们,这时候不妨先看看 el-table
完成渲染后是一个怎么样的 dom
结构组成。笔者就上面的 demo 截了个图如下:
1.表头部分。接着展开看看:
2.表格(body)部分。展开看看:
看完它们的表现形式后,我们真正的打开 table
的源码(位于:packages/components/table/src/table.vue
),看看整体的组成是不是如我们所见的一样布局。由于整个 table 的模板代码已经去到差不多150行了,笔者删减了一些属性代码:
<!-- el