正文

1. 源码

  1. <template>
  2. <div>
  3. <!-- 指定 count 取默认属性 -->
  4. <el-table
  5. :data="tableData"
  6. :span-method="arraySpanMethod"
  7. border
  8. style="width: 100%">
  9. <el-table-column
  10. prop="id"
  11. label="ID"
  12. width="180">
  13. </el-table-column>
  14. <el-table-column
  15. prop="name"
  16. label="姓名">
  17. </el-table-column>
  18. <el-table-column
  19. prop="amount1"
  20. sortable
  21. label="数值 1">
  22. </el-table-column>
  23. <el-table-column
  24. prop="amount2"
  25. sortable
  26. label="数值 2">
  27. </el-table-column>
  28. <el-table-column
  29. prop="amount3"
  30. sortable
  31. label="数值 3">
  32. </el-table-column>
  33. </el-table>
  34. <hr />
  35. <!-- 指定 props -->
  36. <el-table
  37. :data="tableData"
  38. :span-method="arraySpanMethod2"
  39. border
  40. style="width: 100%">
  41. <el-table-column
  42. prop="id"
  43. label="ID"
  44. width="180">
  45. </el-table-column>
  46. <el-table-column
  47. prop="name"
  48. label="姓名">
  49. </el-table-column>
  50. <el-table-column
  51. prop="amount1"
  52. sortable
  53. label="数值 1">
  54. </el-table-column>
  55. <el-table-column
  56. prop="amount2"
  57. sortable
  58. label="数值 2">
  59. </el-table-column>
  60. <el-table-column
  61. prop="amount3"
  62. sortable
  63. label="数值 3">
  64. </el-table-column>
  65. </el-table>
  66. </div>
  67. </template>
  68. <script>
  69. export default {
  70. data() {
  71. return {
  72. tableData: [
  73. {
  74. id: "12987122",
  75. name: "王小1虎",
  76. amount1: "234",
  77. amount2: "3.2",
  78. amount3: 10
  79. },
  80. {
  81. id: "12987121",
  82. name: "王小虎",
  83. amount1: "324",
  84. amount2: "4.43",
  85. amount3: 12
  86. },
  87. {
  88. id: "12987125",
  89. name: "王小虎",
  90. amount1: "621",
  91. amount2: "1.9",
  92. amount3: 9
  93. },
  94. {
  95. id: "12987125",
  96. name: "王小21虎",
  97. amount1: "621",
  98. amount2: "2.2",
  99. amount3: 17
  100. },
  101. {
  102. id: "12987126",
  103. name: "王小2虎",
  104. amount1: "539",
  105. amount2: "2.2",
  106. amount3: 15
  107. }
  108. ],
  109. mergeResult: [],
  110. mergeResult2: [],
  111. props: ["name", "amount2"]
  112. };
  113. },
  114. created() {
  115. // 指定 count 取默认属性
  116. this.mergeResult = this.mergeColumnCells(this.tableData, 2);
  117. // 指定 props
  118. this.mergeResult2 = this.mergeColumnCells(this.tableData, 0, this.props);
  119. console.log(this.mergeResult);
  120. console.log(this.mergeResult2);
  121. },
  122. methods: {
  123. /**
  124. * 多列合并单元格,可以指定某列,下面的 count 和 props 参数,虽然都是非必须的,但是至少得保证有一个
  125. * @param {Array} data 需要处理的数据
  126. * @param {Number} count 非必须参数:需要合并单元格的列的总数量(满足从初始第一列至连续的 count 列的条件)
  127. * @param {Array} props 非必须参数:需要合并单元格的数据列对应的属性列表,示例:['id','name']
  128. * @returns {Array} 储存嵌套的每一列需要合并单元格的合并的格数,示例:[[1,1,2,0,1],[1,2,0,1,1]]
  129. * 两种不同方式的调用示例:
  130. * 指定 count 取默认属性:this.mergeResult = this.mergeColumnCells(this.tableData, 2);
  131. * 指定 props:this.mergeResult = this.mergeColumnCells(this.tableData, 0, this.props);
  132. * 完整的在线示例地址 [element table 多列合并单元格,可以指定某列](https://codepen.io/sunxiaochuan/pen/wvoOXzG)
  133. */
  134. mergeColumnCells(data, count, props) {
  135. if (data && data.length && (count || props)) {
  136. // 先获取到需要合并的属性列表
  137. props = props || [];
  138. // 不存在的话就依照 count 字段开始取默认名称
  139. if (!props.length) {
  140. for (const key in data[0]) {
  141. if (data[0].hasOwnProperty(key)) {
  142. props.push(key);
  143. }
  144. if (props.length === count) {
  145. break;
  146. }
  147. }
  148. }
  149. let saveData = [];
  150. for (let index = 0; index < props.length; index++) {
  151. const prop = props[index];
  152. // 设置初始化值
  153. saveData[index] = [];
  154. let dataList = saveData[index];
  155. // 标记属性值重复的位置
  156. let position;
  157. // 数据计算
  158. for (let i = 0; i < data.length; i++) {
  159. const element = data[i];
  160. // 逻辑:默认的第一条 i === 0 数据将初始化单元格数量为 1,并将标记位置初始为 0;从第二条 i === 1 数据开始与上一条数据做属性比较:一致的话被标记位置的单元格 += 1,相应的当前单元格需要置为 0;否则当前单元格为 1,并重新将当前的索引设置为初始标记位置
  161. if (i === 0) {
  162. dataList.push(1);
  163. position = 0;
  164. } else {
  165. // 判断与上一条数据对应的属性值是否一致,一致的话被标记位置的单元格 += 1,并设置当前的单元格为 0;否则当前单元格为 1,并重新将当前的索引设置为初始标记位置
  166. const prev = data[i - 1];
  167. if (element[prop] === prev[prop]) {
  168. dataList[position] += 1;
  169. dataList.push(0);
  170. } else {
  171. dataList.push(1);
  172. position = i;
  173. }
  174. }
  175. }
  176. }
  177. return saveData;
  178. } else {
  179. return [];
  180. }
  181. },
  182. arraySpanMethod({ row, column, rowIndex, columnIndex }) {
  183. if (columnIndex < 2) {
  184. const _row = this.mergeResult[columnIndex][rowIndex];
  185. return [_row, 1];
  186. }
  187. },
  188. // 指定 props
  189. arraySpanMethod2({ row, column, rowIndex, columnIndex }) {
  190. const index = this.props.indexOf(column.property);
  191. if (index != -1) {
  192. const _row = this.mergeResult2[index][rowIndex];
  193. return [_row, 1];
  194. }
  195. }
  196. }
  197. }
  198. </script>

在线地址

codepen 在线示例:element table 多列合并单元格,可以指定某列