行と列の変換行と列の変換の問題はなぜ発生するのでしょうか?ユーザーが見たいのは複数の列を持つ大きなフォームですが、データベースには「単一列」のデータしか保存されていないためです。そのため、顧客がより便利かつ明確に見ることができるように変換する必要があります。 このような行と列の変換をサポートできる SQL を記述する方法はありますが、記述が複雑で理解しにくいです。 ここでは、具体的な実装方法を示すために、トランスクリプトを例に挙げます。 トランスクリプトの構成を分析するこの好き嫌いの問題は、皆さんもよくご存知でしょう。これは、行と列の変換を必要とする典型的なシナリオです。 トランスクリプト 分析後、次の基本要素が得られます。
要素の分類:
データベースの設計を見てみましょう。一般的には、いくつかの基本テーブルとスコアテーブルが設計されます。
スペースが限られているため、特定の分野については紹介しません。すべてを紹介するのは非常に複雑になります。 vue3 + el-table で作成されたトランスクリプト行と列の変換後のトランスクリプト 科目、生徒、合計点、平均点、最高点、最低点、順位などがすべて表示されます。さまざまな並べ替えオプションも可能です。これがどのように実現されるか見てみましょう。 フロントエンドシミュレーションデータフロントエンドでデータをシミュレートしてみましょう。 (簡易モード) // 件名 - 列を決定する const subject = [ { id: 1, 名前: '数学' }, { id: 2、名前: '中国語' }、 { id: 3, 名前: '物理学' }, { id: 4、名前: '化学' } ] // 学生 - 行を決定する const student = [ { id: 1, name: '张三' }, { id: 2, 名前: 'Li Si' }, { id: 3, 名前: '王五' }, { id: 4、名前: '趙劉' } ] // クラス - const に基づく分類 classes = [ { id: 1, name: '1年生1年生' }, { id: 2、名前: 'クラス2、グレード1' } ] //試験 - 分類基準 const exam = [ { id: 1, name: '中間試験' }, { id: 2、名前: '期末試験' } ] // スコア - コンテンツを決定する const reportCard = [ //シリアル番号 試験ID クラスID 学生ID 科目ID スコア { id: 1, examId: 1, classId: 1, studentId: 1, subjectId: 1, score: 100 }, { id: 2、試験 ID: 1、クラス ID: 1、学生 ID: 1、科目 ID: 2、スコア: 98 }, { id: 3、試験ID: 1、クラスID: 1、学生ID: 1、科目ID: 3、スコア: 90 }, { id: 4、試験ID: 1、クラスID: 1、学生ID: 2、科目ID: 1、スコア: 90 }, { id: 5、試験ID: 1、クラスID: 1、学生ID: 2、科目ID: 2、スコア: 90 }, { id: 6、試験ID: 1、クラスID: 1、学生ID: 2、科目ID: 3、スコア: 40 }, { id: 7、試験ID: 1、クラスID: 1、学生ID: 3、科目ID: 1、スコア: 30 }, { id: 8、試験ID: 1、クラスID: 1、学生ID: 3、科目ID: 2、スコア: 90 }, { id: 8、試験ID: 1、クラスID: 1、学生ID: 3、科目ID: 3、スコア: 40 }, { id: 9、試験ID: 1、クラスID: 1、学生ID: 4、科目ID: 1、スコア: 64 }, { id: 8、試験ID: 1、クラスID: 1、学生ID: 4、科目ID: 2、スコア: 90 }, { id: 9、試験 ID: 1、クラス ID: 1、学生 ID: 4、科目 ID: 3、スコア: 70 } ] el-tableを使用してトランスクリプトを生成するElement-plus は、並べ替え、幅の調整、色の設定、フィルタリングなどの多くの基本機能を実現できる非常に強力なテーブル コンポーネント el-table を提供します。次に、このコンポーネントを使用してトランスクリプトを実装できます。 ヘッダーを決定する行と列の変換の主な特徴は、テーブル ヘッダー (列の数) が固定されておらず、動的に生成する必要があることです。 まず、el-table の要件に従ってテーブル ヘッダーを設定します。 /** * 科目に基づいて表のヘッダーを作成します* * 学生ID、名前、[科目]、合計点、平均点、順位*/ const createTableHead = () => { // 生徒を追加 const head = [ { プロパティ: 'id', ラベル: '学生番号'、 幅: 120 }, { プロパティ: '名前', ラベル: '名前', 幅: 120 }] // 件名を追加 for (const key in subject) { const sub = subject[キー] head.push({ プロパティ: 'sub_' + sub.id, ラベル: サブ名、 幅: 120 }) } head.push({ プロパティ: 'totalScore', ラベル: '合計スコア'、 幅: 120 }) head.push({ プロパティ: 'averageScore', ラベル: '平均スコア'、 幅: 120 }) head.push({ プロパティ: 'ランキング'、 ラベル: 'ランク'、 幅: 120 }) リターンヘッド } ここには 2 種類のヘッダーがあり、1 つは固定で、もう 1 つは件名に基づいて動的に生成されます。 データを決定するテーブル ヘッダーが決定したら、データ部分を決定し、行と列の変換を正式に開始する必要があります。 { id: 1, 名前: '張三'、 サブ_1: 100, サブ_2: 100, ... 合計スコア: 200, 平均スコア: 100, ランキング: 1 } 中間にはさまざまなサブジェクトが存在する可能性があり、属性の命名規則は、プレフィックス「sub_」+ サブジェクト ID です。 成績表を走査してデータを入力します。 /** * 行と列の変換 */ 定数 rowToCol = () => { // オブジェクトベースのスコアリスト const _code = {} // 配列形式のスコアのリスト const _arr = [] // レポートカードを走査します for (const key in reportCard) { const rep = reportCard[キー] if(typeof _code[rep.studentId] === 'undefined') { // レコードがありません。生徒の成績の行を作成し、固定列 data_code[rep.studentId] = { を追加します。 id: rep.studentId, // 学生ID name: (student.filter((item)=>item.id === rep.studentId)[0] || {name:''}).name, // ID に基づいて生徒の名前を取得します totalScore: 0, // 各科目における生徒の合計スコア。後で変更されます averageScore: 0, // 各科目における生徒の平均スコア。後で変更されます ranking: 1 // ランキング。後で変更されます } } // 各科目のスコアを記録する_code[rep.studentId]['sub_' + rep.subjectId] = rep.score } // 下記のように合計スコアと平均スコアを計算します // 下記のようにランキングを計算します return _arr } 成績証明書データを走査し、まず学生 ID に基づいてオブジェクトを作成し、次に科目に基づいて各科目の成績を決定します。 生徒の合計点と平均点を計算する通常、成績証明書には、生徒の合計スコアと平均スコアも記載する必要があります。成績を走査して、合計スコアと平均スコアを計算できます。 ... // 合計スコアと平均スコアを計算します for(const key in _code) { const コード = _code[キー] // 主題を走査する let total = 0 ave = 0とする カウントを 0 にする for (const キー in subject) { const fenshu = code['sub_' + subject[key].id] if (typeof fenshu !== 'undefined') { // スコアがあるので、合計スコアと平均スコアの数を計算します++ 合計 += フェンシュ ave = Math.floor(total / count * 10) / 10 // 小数点第1位を保持します。 // 小数点以下2桁を保持したい場合は、(total / count).toFixed(2) とします。 } } code.totalScore = 合計 code.averageScore = 平均 //オブジェクトデータを配列に変換する data_arr.push(code) } ランキングを計算するトランスクリプトができたので、ランキングを作成する必要があります。 _ranking = 0 とします _arr.sort((a, b) => { // 合計スコアの逆順に b.totalScore - a.totalScore を返す }).forEach((項目) => { // ランキングを設定する _ranking++ _arr.find((a) => a.id === item.id).ranking = _ranking }) 各科目の平均点を計算します。これも一般的な要件です。 以下は公式サイトで紹介されている方法です。本来は合計を出すためのものですが、少し手を加えることで科目の平均点を出すことができます。 // 各科目の平均スコアを計算する let i = 0 const getSummaries = (パラメータ) => { 私は++ (i < 7) の場合 [] を返す const {列、データ} = param; 定数の合計 = []; columns.forEach((列, インデックス) => { (インデックス === 0)の場合{ sums[index] = '平均スコア' 戻る } const values = data.map(item => Number(item[column.property])); if (!values.every(値 => isNaN(値))) { sums[index] = values.reduce((prev, curr) => { 定数値 = Number(curr) if (!isNaN(値)) { 前へ + 次へ } それ以外 { 前へ戻る } }, 0); sums[index] = Math.floor(sums[index] / values.length * 10) / 10 } それ以外 { sums[index] = 'N/A'; } }) 合計を返す 調べてみると、この関数は 7 回呼び出されることがわかりましたが、この回数は行数や列数とは関係ないようです。 各科目の最高点と最低点を記録するトランスクリプトでは、科目の最高点や最低点など、さまざまなデータを計算することもできます。 // 各科目の平均スコア、最高スコア、最低スコアを計算します。const getSummaries = ({ columns }) => { 私は++ (i < 7) の場合 [] を返す 定数の合計 = []; columns.forEach((item, index) => { (item.property.indexOf('sub_') >= 0 )の場合{ 定数 subjectId = item.property.replace('sub_', '')*1 // 件名、平均を計算します。ave = 0 合計を0とする 最大値を0とする 最小値を99999とする const _arr = reportCard.filter((r) => r.subjectId === subjectId) _arr.forEach((アイテム、インデックス) => { sum += item.score // 合計 if (max < item.score) max = item.score // 最高スコアを記録 if (min > item.score) min = item.score // 最低スコアを記録 }) _arr.length === 0 の場合 { sums[index] = '-' // スコアなし} else { // 平均スコアを計算する ave = Math.floor(sum/_arr.length * 10) / 10 合計[インデックス] = `${ave}(${max}-${min})` } } それ以外 { // 計算しない sums[index] = '' } }) sums[0] = '統計' 合計を返す } 今回はreportCardを直接使用して平均スコア、最高スコア、最低スコアを計算します。 並べ替え機能を追加これは el-table の組み込み関数なので、追加するだけです。 <el-テーブル :data="テーブルデータ" スタイル="幅: 100%;高さ: 300px;" :default-sort = "{prop: 'totalScore', order: 'descending'}" :row-class-name="テーブル行クラス名" 国境 概要を表示 :summary-method="getSummaries" > <el-テーブル列 v-for="(item, index) in tableHead" :key="'s'+ インデックス" 修理済み 並べ替え可能 :prop="アイテム.prop" :label="アイテム.ラベル" :width="アイテムの幅"> </el-table-column> </el-table> el-table プロパティ設定。 default-sort デフォルトでは、ランキングは合計スコアの降順で表示されます。 色の区別を強める平均スコアが 60 未満のものを強調表示したい場合はどうすればよいでしょうか? el-table も機能を提供しているので、判断して CSS を設定するだけです。 // 色 const tableRowClassName = ({row, rowIndex}) => { if (row.averageScore < 60) { // 平均スコアが不合格の学生は 'warning-row' を返します。 } else if (row.averageScore > 95) { // 平均スコアが 95 を超える学生は 'success-row' を返します。 } 戻る ''; } ソースコード まとめ アドバンテージ:
欠点:
これで、行と列の変換を実現する vue3+el-table に関するこの記事は終了です。vue3 の行と列の変換に関するより関連性の高いコンテンツについては、123WORDPRESS.COM の以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: select count() と select count(1) の違いと実行方法
>>: Nginx ロケーション設定(ロケーションのマッチング順序)の詳細な説明
NULL および NOT NULL 修飾子、DEFAULT 修飾子、AUTO_INCREMENT 修...
背景クラスメートと row_id の境界問題について話し合ったので、ここで詳しく説明します。 Inn...
pthread_create関数機能紹介pthread_createはUNIX環境のスレッド作成関数...
背景説明: 既存の負荷分散装置には、付加価値状態にある指標があります (増加するだけで減少しないため...
目次序文1. forループ2. whileループとdo-whileループ3. forEach、map...
入力ファイルの HTML コントロールを Web ページに追加します。 <input id=&...
最近、次のような効果を実装しました。再生ボタンをクリックするとタイムラインの再生が開始され、一時停止...
高可用性 Web クラスターを実現する Keepalived+Nginx+Tomcat 1. Ngi...
1. 事業背景マスク レイヤーを使用してユーザーの異常な操作を遮断する方法は、フロントエンドでよく使...
実際に参加したプロジェクトでは、MySQL テーブルのデータ量が数百万に達すると、通常の SQL ク...
高性能で軽量なウェブサービスソフトウェアであるNginxについて高い安定性 システムリソースの消費量...
1. Apacheサーバーのインストールと設定yum インストール httpd -y systemc...
私は頻繁にシステムをインストールするので、インストールのたびにいくつかのソフトウェアを再インストール...
目次結合構文: 1. InnerJOIN: (内部結合) 2. LeftJOIN: (左結合) 3....
1 要件の概要MySQL5.6本番データベースの複数のテーブルのデータは、Oracle11gデータウ...