el-table 合計行セルの結合、セル スタイルの変更

1. 対象となる効果

        ソースコードは以下にありますので、コピーして貼り付けてください

        (1) 先頭に合計線が配置され、文字色が太くなり、合計線の背景色も太くなります

        (2) 合計行の年齢は平均値として計算され文字色は緑色、プロパティは合計として計算され文字色は赤色になります 

2. 原則

2.1. el-table のshow-summary合計行はデフォルトで最後に配置されます。

        次の CSS を追加するだけです:親セレクター /deep/ 子セレクター スタイルの浸透を実現します。

/* 合计行位置修改开始 */
.el-table {
    display: flex;
    flex-direction: column;
}

.el-table /deep/ .el-table__body-wrapper {
    order: 1;
}

/* 合计行位置修改结束*/

2.2. 合計行全体のスタイルを変更する

/* 合计行整体样式修改开始 */
.el-table /deep/ .el-table__footer-wrapper tbody td {
    background: black;
    color: white;
    font-weight: bolder;
}

/* 合计行整体样式修改结束*/

2.3. 要約メソッド: :summary-method="getSummaries"

 // 合计行方法
        getSummaries(param) {
            const { columns, data } = param;
            const sums = [];
            columns.forEach((column, index) => {
                if (column.property == 'date') {
                    sums[index] = '总价';
                    return;
                }

                // values是每一列的数据是一个数组
                const values = data.map(item => Number(item[column.property]));
                
                // 数字列才进行合计计算
                if (!values.every(value => isNaN(value))) {
                    // 对values进行一个累加操作,累加那些非NAN的值
                    const total = values.reduce((prev, curr) => {
                        const value = Number(curr);
                        if (!isNaN(value)) {
                            return prev + curr;
                        } else {
                            return prev;
                        }
                    }, 0);

                    // 年龄计算平均值
                    if (column.property == 'age') {
                        sums[index] = total / data.length
                    }

                    // 财产计算总数
                    if (column.property == 'money') {
                        sums[index] = total}
                    }

                }
            });

            // 将合计结果返回,是一个数组,每个位置的值与表格的列一一对应
            return sums
        }

        columns はオブジェクトの配列である各列の情報を表示します。

        dataは各行の情報であり、行全体をカウントしないオブジェクト配列でもあります。

        sums は合計行であり、 typescriptのタプルです。つまり、異なる型の要素を配列に格納できます。

  

2.4、合計行セルのスタイル

        2.4.1、cssメソッド

.el-table /deep/ .el-table__footer-wrapper tbody td:nth-child(3) {
    color: lightgreen;
    font-weight: bolder;
}

.el-table /deep/ .el-table__footer-wrapper tbody td:nth-child(4) {
    color: red;
    font-weight: bolder;
}

        欠点: 各列の位置を手動で計算する必要があり、一度列の位置が変更されると、メンテナンスが容易ではありません。

        2.4.2、jsx の方法

        合計行で jsx を返し、VNode を生成し、スタイルを動的に生成します

 // 年龄计算平均值(绿色)
                    if (column.property == 'age') {
                        sums[index] = <span class={'green'}>{total / data.length}</span>
                    }

                    // 财产计算总数(红色)
                    if (column.property == 'money') {
                        sums[index] = <span class={'red'}>{total}</span>
                    }
.red {
    color: red;
    font-weight: bolder;
}

.green {
    color: lightgreen;
    font-weight: bolder;
}

        

       合計は VNode を返します

         

2.5. 合計行セルの結合

        2.5.1、他の人のブログのやり方(エラーが報告されます)        

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

        2.5.2、elementUI で行を結合する方法

        :span-method には合計行数は含まれません

        2.5.3. この記事の方法(推奨

                方法 1 に基づく変換:

 watch: {
        tableData: {
            immediate: true,
            handler() {
                setTimeout(() => {
                    const tds = document.querySelectorAll('#table .el-table__footer-wrapper tr>td');
                    tds[0].colSpan = 2;
                    tds[0].style.textAlign = 'center'
                    tds[1].style.display = 'none'
                }, 0)
            }
        }
    },

                なぜこのようなことが可能なのでしょうか?              

        Vue では、テンプレートを使用して HTML を作成することをお勧めします。ただし、実際の DOM ノードではありません。Vue は最初にオブジェクト内のrender関数を使用して仮想 DOM ノードを生成し、それをマウントしますマウントされた実際の DOM は非同期でレンダリングされ状態が変更された後も非同期でレンダリングされますdocument.querySelectorAll操作はコード内で同期タスクとして定義されており、イベント キューは次のようになります。

        同期キュー: dom要素を取得
        非同期キュー: 仮想ノードから実ノードに変換してレンダリング同期→非同期の
実行プロセス         によりセルのマージができない

setTimeout        を使用して実行のために要素を非同期キューに配置し、ページがロードされた後に dom 要素を取得すると成功します。

 

2.6. 合計行には固定列があります

        合計行に固定列がある場合、次の問題が発生します。

        (1)固定列の合計行が下まで伸びました

        (2)セル結合の効果が消える

 

 

        次の CSS を追加し、いくつかの JS を変更します

/* 存在固定列时,合计行位置修改开始 */
.el-table /deep/ .el-table__fixed {
    display: flex;
    flex-direction: column;
}

.el-table /deep/ .el-table__fixed-footer-wrapper,
.el-table /deep/ .el-table__fixed-body-wrapper,
.el-table /deep/ .el-table__fixed-header-wrapper {
    position: initial;
}

.el-table /deep/ .el-table__fixed-body-wrapper {
    order: 1;
}

.el-table /deep/ .el-table__fixed-footer-wrapper tbody td.el-table__cell {
    border-top: none;
    background: black;
    color: white;
    font-weight: bolder;

}

/* 存在固定列时,合计行位置修改开始 */

    

 

        最終的な効果は以下の通りです。

3. ソースコード

       app.vue

<template>
  <div id="app">
    <SummaryTable></SummaryTable>
  </div>
</template>
 
<script>
import SummaryTable from '@/components/SummaryTable'
export default {
  components: {
    SummaryTable
  },
  name: 'App',
  data() {
    return {

    }
  },
}
</script>
 
<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

        SummaryTable.vue

<template>
    <div>
        <el-table ref="table" id="table" :data="tableData" border style="width: 100%" show-summary
            :summary-method="getSummaries">
            <el-table-column prop="date" label="日期" width="180" fixed="left">
            </el-table-column>
            <el-table-column prop="name" label="姓名" width="180" fixed="left">
            </el-table-column>
            <el-table-column prop="age" label="年龄"></el-table-column>
            <el-table-column prop="age" label="年龄"></el-table-column>
            <el-table-column prop="age" label="年龄"></el-table-column>
            <el-table-column prop="age" label="年龄"></el-table-column>
            <el-table-column prop="age" label="年龄"></el-table-column>
            <el-table-column prop="age" label="年龄"></el-table-column>
            <el-table-column prop="age" label="年龄"></el-table-column>
            <el-table-column prop="age" label="年龄"></el-table-column>
            <el-table-column prop="age" label="年龄"></el-table-column>
            <el-table-column prop="age" label="年龄"></el-table-column>
            <el-table-column prop="age" label="年龄"></el-table-column>
            <el-table-column prop="money" label="财产"></el-table-column>
            <el-table-column prop="money" label="财产"></el-table-column>
            <el-table-column prop="money" label="财产"></el-table-column>
            <el-table-column prop="money" label="财产"></el-table-column>
        </el-table>
    </div>
</template>
   
<script>

export default {
    name: 'App',
    data() {
        return {
            tableData: [{
                date: '2016-05-01',
                name: '王小虎',
                age: 13,
                money: 100
            }, {
                date: '2016-05-02',
                name: '王小虎',
                age: 25,
                money: 333
            }, {
                date: '2016-05-03',
                name: '王小虎',
                age: 33,
                money: 555
            }, {
                date: '2016-05-04',
                name: '王小虎',
                age: 23,
                money: 200
            },
            {
                date: '2016-05-05',
                name: '王小虎',
                age: 26,
                money: 666
            }],
        }
    },
    watch: {
        tableData: {
            immediate: true,
            handler() {
                setTimeout(() => {
                    const tds = document.querySelectorAll('#table .el-table__fixed-footer-wrapper tr>td');
                    tds[0].colSpan = 2;
                    tds[0].style.textAlign = 'center'
                    tds[1].style.display = 'none'
                }, 0)
            }
        }
    },
    methods: {
        // 合计行方法
        getSummaries(param) {
            const { columns, data } = param;
            const sums = [];
            columns.forEach((column, index) => {
                if (column.property == 'date') {
                    sums[index] = '总价';
                    return;
                }

                // values是每一列的数据是一个数组
                const values = data.map(item => Number(item[column.property]));
                if (!values.every(value => isNaN(value))) {
                    // 对values进行一个累加操作,累加那些非NAN的值
                    const total = values.reduce((prev, curr) => {
                        const value = Number(curr);
                        if (!isNaN(value)) {
                            return prev + curr;
                        } else {
                            return prev;
                        }
                    }, 0);

                    // 年龄计算平均值(绿色)
                    if (column.property == 'age') {
                        sums[index] = <span class={'green'}>{total / data.length}</span>
                    }

                    // 财产计算总数(红色)
                    if (column.property == 'money') {
                        sums[index] = <span class={'red'}>{total}</span>
                    }

                }
            });
            // 将合计结果返回,是一个数组,每个位置的值与表格的列一一对应
            return sums
        }
    }
}
</script>
   
<style scoped>
.red {
    color: red;
    font-weight: bolder;
}

.green {
    color: lightgreen;
    font-weight: bolder;
}

/* 存在固定列时,合计行位置修改开始 */
.el-table /deep/ .el-table__fixed {
    display: flex;
    flex-direction: column;
}

.el-table /deep/ .el-table__fixed-footer-wrapper,
.el-table /deep/ .el-table__fixed-body-wrapper,
.el-table /deep/ .el-table__fixed-header-wrapper {
    position: initial;
}

.el-table /deep/ .el-table__fixed-body-wrapper {
    order: 1;
}

.el-table /deep/ .el-table__fixed-footer-wrapper tbody td.el-table__cell {
    border-top: none;
    background: black;
    color: white;
    font-weight: bolder;
}

/* 存在固定列时,合计行位置修改开始 */

/* 默认有1px去掉样式影响 */
.el-table /deep/ .el-table__fixed::before {
    height: 0;
}

/* 合计行整体样式修改开始 */
.el-table /deep/ .el-table__footer-wrapper tbody td {
    background: black;
    color: white;
    font-weight: bolder;
}

/* 合计行整体样式修改结束*/


/* 合计行位置修改开始 */
.el-table {
    display: flex;
    flex-direction: column;
}

.el-table /deep/ .el-table__body-wrapper {
    order: 1;
}

/* 合计行位置修改结束*/
</style>

おすすめ

転載: blog.csdn.net/weixin_42375707/article/details/131260574