万恶的产品设计一个动态表格合并的功能,曾经实现了一版运用js进行dom元素的拼接,发现代码量好大,
后来产品再次设计了类似表格,复用之前代码感觉心好累,所以我就花十分钟仔细想了下,得出下面的解决方案。
最终效果为 https://goddywu.github.io/html/demo/table_combine.html
源码地址 https://github.com/Goddywu/html/blob/master/demo/table_combine.html
场景
想象一个情景,我们需要记录用户的操作,并展示出来,用户在相邻时间点做的同样操作,我们希望它们占据同一个格子。
思路
- 如果我们希望做一个3X2的表格,第二列合并前两格,那么我们的HTML代码将是
<table>
<tr>
<td>1行1列</td>
<td rowspan="2">第2列前两格</td>
</tr>
<tr>
<td>2行1列</td>
</tr>
<tr>
<td>3行1列</td>
<td>3行2列</td>
</tr>
<table>
- 观察需要合并的第二列,合并前我们每个行元素tr内需要有第二列的td元素,假设1代表存在,那么第二列的td存在情况为
[1, 1, 1]
- 观察合并后的第二列的td元素存在情况,为
[1, 0, 1]
- 如果将rowspan的值代替掉第一个td元素,那么我们得到的数组为
[2, 0, 1]
,数组名称设置为temp - 有了这个数组就好办了,我们可以用vue的v-on绑定rowspan,用v-if来去掉例如第二行不需要的第二个td元素。
- 数据为
#已知数据
data = [
['2018-01-01', '买包子'],
['2018-01-02', '吃包子'],
['2018-01-03', '吃包子']
]
#我们需要计算出的数组
array = [2, 0, 1]
- 我们的代码将是
<table>
<tr v-for='(i, index) in data'>
<td>
{{i[0]}}
</td>
<td v-if='temp[index] != 0'>
{{i[1]}}
</td>
</tr>
</table>
接下来,就是核心:如何得出数组array
思路:
建立一个temp作缓存变量,count作为计数器,遍历data数组,如果值与temp相同,则计数器加1,如果不同,则temp值赋值为当前值,并且计数器重置。
所有代码戳链接