当前位置:   article > 正文

el-table合计行单元格合并、单元格样式修改_el-table show-summary

el-table show-summary

1、目标效果

        源码放在下面,复制粘贴即可

        (1)合计行放在头部,且字体颜色变粗、合计行背景色变粗

        (2)合计行年龄算平均值且字体颜色为绿色,财产算总数且字体颜色为红色 

2、原理

2.1、el-table中show-summary 合计行默认放在尾部

        加上如下css即可:父选择器  /deep/ 子选择器实现样式穿透

  1. /* 合计行位置修改开始 */
  2. .el-table {
  3. display: flex;
  4. flex-direction: column;
  5. }
  6. .el-table /deep/ .el-table__body-wrapper {
  7. order: 1;
  8. }
  9. /* 合计行位置修改结束*/

2.2、合计行整体样式修改

  1. /* 合计行整体样式修改开始 */
  2. .el-table /deep/ .el-table__footer-wrapper tbody td {
  3. background: black;
  4. color: white;
  5. font-weight: bolder;
  6. }
  7. /* 合计行整体样式修改结束*/

2.3、合计方法::summary-method="getSummaries"

  1. // 合计行方法
  2. getSummaries(param) {
  3. const { columns, data } = param;
  4. const sums = [];
  5. columns.forEach((column, index) => {
  6. if (column.property == 'date') {
  7. sums[index] = '总价';
  8. return;
  9. }
  10. // values是每一列的数据是一个数组
  11. const values = data.map(item => Number(item[column.property]));
  12. // 数字列才进行合计计算
  13. if (!values.every(value => isNaN(value))) {
  14. // 对values进行一个累加操作,累加那些非NAN的值
  15. const total = values.reduce((prev, curr) => {
  16. const value = Number(curr);
  17. if (!isNaN(value)) {
  18. return prev + curr;
  19. } else {
  20. return prev;
  21. }
  22. }, 0);
  23. // 年龄计算平均值
  24. if (column.property == 'age') {
  25. sums[index] = total / data.length
  26. }
  27. // 财产计算总数
  28. if (column.property == 'money') {
  29. sums[index] = total}
  30. }
  31. }
  32. });
  33. // 将合计结果返回,是一个数组,每个位置的值与表格的列一一对应
  34. return sums
  35. }

        columns展示每一列的信息,是一个对象数组

        data为每一行的信息,也是一个对象数组,不算上合计行哦!

        sums为合计行,在typescript中是一个元祖,即数组里面可以存放不同类型的元素

  

2.4、合计行单元格样式

        2.4.1、css方式

  1. .el-table /deep/ .el-table__footer-wrapper tbody td:nth-child(3) {
  2. color: lightgreen;
  3. font-weight: bolder;
  4. }
  5. .el-table /deep/ .el-table__footer-wrapper tbody td:nth-child(4) {
  6. color: red;
  7. font-weight: bolder;
  8. }

        缺点:需要手动计算每列的位置,一旦列的位置发生变化,不好维护

        2.4.2、jsx方式

        合计行中返回jsx,生成一个VNode,动态生成样式

  1. // 年龄计算平均值(绿色)
  2. if (column.property == 'age') {
  3. sums[index] = <span class={'green'}>{total / data.length}</span>
  4. }
  5. // 财产计算总数(红色)
  6. if (column.property == 'money') {
  7. sums[index] = <span class={'red'}>{total}</span>
  8. }
  1. .red {
  2. color: red;
  3. font-weight: bolder;
  4. }
  5. .green {
  6. color: lightgreen;
  7. font-weight: bolder;
  8. }

        

        sums返回VNode

         

2.5、合计行单元格合并

        2.5.1、别人博客的方式(会报错)        

  1. watch: {
  2. 表格数据: {
  3. immediate: true,
  4. handler() {
  5. const tds = document.querySelectorAll('#table .el-table__footer-wrapper tr>td');
  6. tds[0].colSpan = 2;
  7. tds[0].style.textAlign = 'center'
  8. tds[1].style.display = 'none'
  9. }
  10. }
  11. },

        2.5.2、elementUI中合并行的方法

        :span-method是不包括合计行的

        2.5.3、本篇文章的方法 (推荐

                在方法一的基础上改造:

  1. watch: {
  2. tableData: {
  3. immediate: true,
  4. handler() {
  5. setTimeout(() => {
  6. const tds = document.querySelectorAll('#table .el-table__footer-wrapper tr>td');
  7. tds[0].colSpan = 2;
  8. tds[0].style.textAlign = 'center'
  9. tds[1].style.display = 'none'
  10. }, 0)
  11. }
  12. }
  13. },

                为什么这样却可以?              

        Vue 推荐使用 template 来创建 HTML。但不是真实的DOM节点。vue会先利用对象中的render 函数,生成虚拟DOM节点并挂载挂载的真实DOM是进行异步渲染的并且在修改完状态后也是异步的方式进行渲染。代码中将document.querySelectorAll操作定义为同步任务,此时事件队列应该是:

        同步队列:获取dom元素
        异步队列:从虚拟节点转真实节点并进行渲染
        根据先同步后异步的执行流程,是无法合并单元格的

        使用setTimeout 可以将元素放在异步队列执行,等页面加载完毕之后在获取dom元素就可以成功了!

 

2.6、合计行存在固定列

        合计行存在固定列时,会出现如下问题:

        (1)固定列中的合计行跑到底部了

        (2)合并单元格效果消失

 

 

        加上如下css以及修改部分js

  1. /* 存在固定列时,合计行位置修改开始 */
  2. .el-table /deep/ .el-table__fixed {
  3. display: flex;
  4. flex-direction: column;
  5. }
  6. .el-table /deep/ .el-table__fixed-footer-wrapper,
  7. .el-table /deep/ .el-table__fixed-body-wrapper,
  8. .el-table /deep/ .el-table__fixed-header-wrapper {
  9. position: initial;
  10. }
  11. .el-table /deep/ .el-table__fixed-body-wrapper {
  12. order: 1;
  13. }
  14. .el-table /deep/ .el-table__fixed-footer-wrapper tbody td.el-table__cell {
  15. border-top: none;
  16. background: black;
  17. color: white;
  18. font-weight: bolder;
  19. }
  20. /* 存在固定列时,合计行位置修改开始 */

    

 

        最终效果如下:

3、源码

        App.vue

  1. <template>
  2. <div id="app">
  3. <SummaryTable></SummaryTable>
  4. </div>
  5. </template>
  6. <script>
  7. import SummaryTable from '@/components/SummaryTable'
  8. export default {
  9. components: {
  10. SummaryTable
  11. },
  12. name: 'App',
  13. data() {
  14. return {
  15. }
  16. },
  17. }
  18. </script>
  19. <style>
  20. #app {
  21. font-family: Avenir, Helvetica, Arial, sans-serif;
  22. -webkit-font-smoothing: antialiased;
  23. -moz-osx-font-smoothing: grayscale;
  24. text-align: center;
  25. color: #2c3e50;
  26. margin-top: 60px;
  27. }
  28. </style>

        SummaryTable.vue

  1. <template>
  2. <div>
  3. <el-table ref="table" id="table" :data="tableData" border style="width: 100%" show-summary
  4. :summary-method="getSummaries">
  5. <el-table-column prop="date" label="日期" width="180" fixed="left">
  6. </el-table-column>
  7. <el-table-column prop="name" label="姓名" width="180" fixed="left">
  8. </el-table-column>
  9. <el-table-column prop="age" label="年龄"></el-table-column>
  10. <el-table-column prop="age" label="年龄"></el-table-column>
  11. <el-table-column prop="age" label="年龄"></el-table-column>
  12. <el-table-column prop="age" label="年龄"></el-table-column>
  13. <el-table-column prop="age" label="年龄"></el-table-column>
  14. <el-table-column prop="age" label="年龄"></el-table-column>
  15. <el-table-column prop="age" label="年龄"></el-table-column>
  16. <el-table-column prop="age" label="年龄"></el-table-column>
  17. <el-table-column prop="age" label="年龄"></el-table-column>
  18. <el-table-column prop="age" label="年龄"></el-table-column>
  19. <el-table-column prop="age" label="年龄"></el-table-column>
  20. <el-table-column prop="money" label="财产"></el-table-column>
  21. <el-table-column prop="money" label="财产"></el-table-column>
  22. <el-table-column prop="money" label="财产"></el-table-column>
  23. <el-table-column prop="money" label="财产"></el-table-column>
  24. </el-table>
  25. </div>
  26. </template>
  27. <script>
  28. export default {
  29. name: 'App',
  30. data() {
  31. return {
  32. tableData: [{
  33. date: '2016-05-01',
  34. name: '王小虎',
  35. age: 13,
  36. money: 100
  37. }, {
  38. date: '2016-05-02',
  39. name: '王小虎',
  40. age: 25,
  41. money: 333
  42. }, {
  43. date: '2016-05-03',
  44. name: '王小虎',
  45. age: 33,
  46. money: 555
  47. }, {
  48. date: '2016-05-04',
  49. name: '王小虎',
  50. age: 23,
  51. money: 200
  52. },
  53. {
  54. date: '2016-05-05',
  55. name: '王小虎',
  56. age: 26,
  57. money: 666
  58. }],
  59. }
  60. },
  61. watch: {
  62. tableData: {
  63. immediate: true,
  64. handler() {
  65. setTimeout(() => {
  66. const tds = document.querySelectorAll('#table .el-table__fixed-footer-wrapper tr>td');
  67. tds[0].colSpan = 2;
  68. tds[0].style.textAlign = 'center'
  69. tds[1].style.display = 'none'
  70. }, 0)
  71. }
  72. }
  73. },
  74. methods: {
  75. // 合计行方法
  76. getSummaries(param) {
  77. const { columns, data } = param;
  78. const sums = [];
  79. columns.forEach((column, index) => {
  80. if (column.property == 'date') {
  81. sums[index] = '总价';
  82. return;
  83. }
  84. // values是每一列的数据是一个数组
  85. const values = data.map(item => Number(item[column.property]));
  86. if (!values.every(value => isNaN(value))) {
  87. // 对values进行一个累加操作,累加那些非NAN的值
  88. const total = values.reduce((prev, curr) => {
  89. const value = Number(curr);
  90. if (!isNaN(value)) {
  91. return prev + curr;
  92. } else {
  93. return prev;
  94. }
  95. }, 0);
  96. // 年龄计算平均值(绿色)
  97. if (column.property == 'age') {
  98. sums[index] = <span class={'green'}>{total / data.length}</span>
  99. }
  100. // 财产计算总数(红色)
  101. if (column.property == 'money') {
  102. sums[index] = <span class={'red'}>{total}</span>
  103. }
  104. }
  105. });
  106. // 将合计结果返回,是一个数组,每个位置的值与表格的列一一对应
  107. return sums
  108. }
  109. }
  110. }
  111. </script>
  112. <style scoped>
  113. .red {
  114. color: red;
  115. font-weight: bolder;
  116. }
  117. .green {
  118. color: lightgreen;
  119. font-weight: bolder;
  120. }
  121. /* 存在固定列时,合计行位置修改开始 */
  122. .el-table /deep/ .el-table__fixed {
  123. display: flex;
  124. flex-direction: column;
  125. }
  126. .el-table /deep/ .el-table__fixed-footer-wrapper,
  127. .el-table /deep/ .el-table__fixed-body-wrapper,
  128. .el-table /deep/ .el-table__fixed-header-wrapper {
  129. position: initial;
  130. }
  131. .el-table /deep/ .el-table__fixed-body-wrapper {
  132. order: 1;
  133. }
  134. .el-table /deep/ .el-table__fixed-footer-wrapper tbody td.el-table__cell {
  135. border-top: none;
  136. background: black;
  137. color: white;
  138. font-weight: bolder;
  139. }
  140. /* 存在固定列时,合计行位置修改开始 */
  141. /* 默认有1px去掉样式影响 */
  142. .el-table /deep/ .el-table__fixed::before {
  143. height: 0;
  144. }
  145. /* 合计行整体样式修改开始 */
  146. .el-table /deep/ .el-table__footer-wrapper tbody td {
  147. background: black;
  148. color: white;
  149. font-weight: bolder;
  150. }
  151. /* 合计行整体样式修改结束*/
  152. /* 合计行位置修改开始 */
  153. .el-table {
  154. display: flex;
  155. flex-direction: column;
  156. }
  157. .el-table /deep/ .el-table__body-wrapper {
  158. order: 1;
  159. }
  160. /* 合计行位置修改结束*/
  161. </style>
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/113702
推荐阅读
相关标签
  

闽ICP备14008679号