<div>
<p></p>
<div style="text-align:center;">
<img alt="65bbd2e22df92cebeeefc49af2c4585f.png" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-bbaac2408252517f2b5dc70aa9a1aea3.png">
</div>
<h2>前言</h2>
<blockquote>
Github原文:github.com/qiud...
<br> 本文介绍内容包括:
<br>1. Element UI 实现表头表列固定思考与总结
<br>2. translate3d如何实现表头表列固定
</blockquote>
<p>书承上文,在前文【Vue进阶】青铜选手,如何自研一套UI库中介绍了Vue组件库的开发细节,举例实现了button、table等组件的开发。在<b>Ange</b>这个UI库中,我实现了一个内容高可定制的表格组件:可固定表头和表列,内容则自行定义。</p>
<p>首先要承认,这个table组件实现的功能很简单:</p>
<ul><li>创建表格展示数据</li><li>可固定表头</li><li>可固定表列</li><li>可实现简易版多级表头</li></ul>
<p>表格组件是UI库里面最为复杂的组件之一,项目中使用表格的场景特别多,我们很难覆盖所有人的需求,比较常见的就有:</p>
<ul><li>固定表头</li><li>固定表左/右侧列</li><li>多级表头 </li><li>勾选行数据</li><li>展开行数据</li><li>数据排序</li></ul>
<p>从作用对象来看,这些需求又可归为<b>影响布局</b>(Eg: 固定表头表列)和<b>影响数据</b>(Eg: 勾选数据)两个大类。在<b>Ange UI</b>的table组件中,仅仅实现了影响布局这个类下面的部分功能,该组件不操作数据,甚至具体到使用tr、td标签(以及td里面如何包裹数据)展示数据也是由使用者自己定义的。狠狠点击这里在线查看示例,或者查看代码:</p>
<div class="blockcode">
<pre class="blockcode"><code><ag-table offsetTop="57.5">
<tr slot="thead">
<!-- 定义表头列 -->
<th v-if="isExpand">姓名</th>
<th v-for="(each, index) in singleTableHead" :key="index">{<!-- -->{ each }}</th>
</tr>
<tr v-for="(each, index) in singleTableBody" slot='tbody' :key="`tbody-${index}`">
<!-- 渲染表体内容 -->
<td v-if="isExpand">{<!-- -->{ each.name }}</td>
<td>{<!-- -->{ each.verdict }}</td>
<td>{<!-- -->{ each.song }}</td>
</tr>
</ag-table></code></pre>
</div>
<p>通过<b>插槽slot</b>指定thead或是tbody。简单就意味着精细和可拓展性强,同时带来的问题就是用户的使用成本高了(比如实现数据选择功能,当然<code>ag-table</code>在不操作源数据的原则下也能拓展出这个功能)。</p>
<h2>谈谈element的固定表头表列</h2>
<p>从浏览器中审查Element table组件的渲染效果看,Element实现固定表头表列的方式是:将固定的部分(如表头)和不固定的部分(如表体)拆分放在不同区域(不同的div下),设置表体所在区域可滚动即可,然后再通过一定的手段(如阴槽、表格数据备份)去同步不同区域之间的布局。</p>
<p>在一篇饿了么专题的文章中,详细阐述了固定表头表列的实现。下面简单总结并整理其中存在的问题。</p>
<h3>1.1 固定表头的思路</h3>
<p>从浏览器中审查table组件的渲染效果看: </p>
<p></p>
<div style="text-align:center;">
<img alt="fecfe0ddc8761d2584eaa9f5b4a3feb3.png" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-2f2eef462b061f9d29f21f811561086c.png">
</div>
<p> 表头和表体分别放在了两个不同的div区域:<b><code>el-table__header-wrapper</code></b> & <b><code>el-table__body-wrapper</code></b>,如此表体内容超出容器高度时,会出现滚动条,只在自己区域内滚动,达到了表头固定的效果。这样的实现导致了两个问题: </p>
<ul><li>两个表格宽度不一致:表体所在的区域多出了一条滚动条</li><li>两个表格之间的列宽如何保持一致</li></ul>
<p>针对上面的问题,element也做了处理,引用饿了么文中一张图片: </p>
<p></p>
<div style="text-align:center;">
<img alt="0f3bbb2f7cc6cdea584be40ad46f29f1.png" src="https://beijingoptbbs.oss-cn-beijing.aliyuncs.com/cs/5606289-c5b4461853ccd25f606d8bfd9d757a62.png">
</div>
<p> 在表头部分增加一个<b>Gutter元素</b>,虚拟成滚动条去占据一定宽度(图片右上角粉色的竖条),宽度一致的处理则是要求用户使用的时候个<b>传入每个列的宽度</b>。</p>
<p>这种实现方式有什么缺点呢? </p>
<ul><li>额外维护新增元素(Gutter); </li><li>自定义每列宽度增加用户使用成本,理想情况应该能根据文本内容自适应; </li><li>表体的滚动条上不去(滚不到表头的顶部),这个让我很捉急; </li><li>表头 |
|