Vue を使用して 2 つのデータ セットの違いを比較する視覚化コンポーネントの詳細な説明

Vue を使用して 2 つのデータ セットの違いを比較する視覚化コンポーネントの詳細な説明

タイトルの通り、友人がこのようなニーズを抱えており、よくあることのようなので参考までに投稿します

必要:

el-table を使用して 2 セットのデータを表示します。差異のあるセルは赤で表示され、新しく追加されたセルは緑で表示されます。

要点:

  • 比較する必要がある2つのデータセットを含むデータセットが必要です。
  • データの行が他のデータに存在するかどうか(新しく追加されたかどうか)を判断するには、一意のキーが必要です。
  • テーブルをレンダリングするためのテーブル列構成を受け入れます。違いは構成されたデータのみに基づいており、他のデータを比較する必要はありません。

これまでの要点に従って、コンポーネントのプロパティを確立できます。

小道具: {
  ユニークキー: {
    タイプ: 文字列、
    デフォルト: "id"
  },
  データグループ: {
    タイプ: 配列、
    バリデータ: val => val.length === 2
  },
  列: {
    タイプ: 配列、
    必須: true
  }
}

一意の ID はデフォルトで id になります。列の形式は el-table-column に従い、{label, prop, ...} として定義されます。

コンポーネントの基本的なスタイルも非常にシンプルです。

<テンプレート>
  <div class="diff-table-container">
    <el-テーブル
      v-for="(data, i) がcompletedData内に存在する"
      :key="i"
      :data="データ"
      :row-style="行スタイルをマーク"
      :cell-style="マークセルスタイル"
    >
      <el-table-column v-for="列内の項目" :key="`${i}${item.prop}`" align="center" v-bind="item" />
    </el-table>
  </div>
</テンプレート>

<style lang="scss" スコープ>
.diff-table-container {
  ディスプレイ: フレックス;
  align-items:flex-start;
  .el-table + .el-table {
    左マージン: 20px;
  }
}
</スタイル>

上図のように、2 つのテーブルは単純に水平に配置されます。ここでのcompletedDataは、diffプロセスが完了した後のデータを指し、その形式は渡されたdataGroupと同じです。 markRowStyles と markRowStyles はどちらも el-table によって提供され、それぞれ行と列のスタイルを参照します。値はオブジェクトまたはオブジェクトを返す関数です。

次に、2 つのシンボルを定義します。データを比較すると、データがマークされます。マークにシンボルを使用すると、属性名の競合を防ぐことができます。

データ() {
  戻る {
    DIFF_CELL_KEY: Symbol("diffCells"), // 差異のあるセルの名前を格納する配列 COMPLETED_KEY: Symbol("completed") // 完了した処理をマークします };
}

すると、diff のスタイル処理も直接決定できるようになります。

メソッド: {
  // 処理後、マークがない場合は、1セットのデータ、つまり新しいデータにのみ表示されることを意味します markRowStyles({ row }) {
    戻る (
      !row[this.COMPLETED_KEY] && {
        背景色: "#E1F3D8"
      }
    );
  },
  // 現在の行の一意のキーに基づいて、マップにキャッシュされた行データを検索します // つまり、dataGroup[0].find(item => item[uniqueKey] === row[uniqueKey])
  // 次に、DIFF_CELL_KEY配列に現在の列の属性名が含まれているかどうかを判断します。markCellStyles({ row, column }) {
    const { $_cacheMap、uniqueKey、DIFF_CELL_KEY } = this;
    _cacheRow を $_cacheMap.get(行[一意のキー]);
    戻る (
      _cacheRow &&
      _cacheRow[DIFF_CELL_KEY].includes(列.property) && {
        背景色: "#FDE2E2"
      }
    );
  }
}

最後のステップは、計算された属性を使用して直接実行される diff の処理です。処理が完了すると、新しいデータが返されます。

計算: {
  // 完了したデータの処理completedData({ dataGroup, uniqueKey, columns, DIFF_CELL_KEY, COMPLETED_KEY }) {
    // この手順は不要です。ビジネス要件に従って、元のデータを変更できない場合は、ディープ コピーを作成します。const _dataGroup = deepClone(dataGroup);
    // Map<string|number, object>、私はTSに詳しくありませんが、これはこのように書くべきで、実際はrow[unique]: rowです
    const cacheMap = 新しい Map();
    // まず最初のデータセットを走査し、DIFF_CELL_KEY配列を初期化し、それをマップに格納します for (const _row of _dataGroup[0]) {
      _row[DIFF_CELL_KEY] = [];
      キャッシュマップを設定します(_row[uniqueKey], _row);
    }
    // 2番目のデータセットを走査します。内部に別のループがあります。列で定義された属性のみが処理されるため、他の属性は比較されません for (const _row of _dataGroup[1]) {
      for (const { prop } 列) {
        // 一意のキーの場合は直接スキップします if (prop === uniqueKey) continue;
        // キャッシュから同じデータを検索 const original = cacheMap.get(_row[uniqueKey]);
        // 見つからない場合は、このデータが新しく追加されたことを意味するので、スキップします if (!original) continue;
        // それ以外の場合は、2 つのデータ セットにマークを付けて、処理済みであり、新しく追加されたものではないことを示します。_row[COMPLETED_KEY] = true;
        オリジナル[COMPLETED_KEY] = true;
        // 最後に、2 つのプロパティ値を比較します。同じ場合は、DIFF_CELL_KEY 配列にプッシュします。// DIFF_CELL_KEY 配列は最初のデータ セットにのみ存在することに注意してください。// 違いはすべてのテーブルに表示されるため、すべてのデータ セットに保存する必要はありません。_row[prop] !== original[prop] && original[DIFF_CELL_KEY].push(prop);
      }
    }
    // スタイルを処理するときに使用されるため、マップのコピーをここに保存します。$_cacheMap = cacheMap;
    _dataGroup を返します。
  }
}

完了しました。最後に完全なコードを貼り付けます。

<テンプレート>
  <div class="diff-table-container">
    <el-テーブル
      v-for="(data, i) がcompletedData内に存在する"
      :key="i"
      :data="データ"
      :row-style="行スタイルをマーク"
      :cell-style="マークセルスタイル"
    >
      <el-table-column v-for="列内の項目" :key="`${i}${item.prop}`" v-bind="item" align="center" />
    </el-table>
  </div>
</テンプレート>

<スクリプト>
関数 deepClone(val) {
  // ディープコピーを行うかどうかは要件によって異なります。 return val;
}

エクスポートデフォルト{
  名前: "DiffTable",
  小道具: {
    ユニークキー: {
      タイプ: 文字列、
      デフォルト: "id"
    },
    データグループ: {
      タイプ: 配列、
      バリデータ: val => val.length === 2
    },
    列: {
      タイプ: 配列、
      必須: true
    }
  },
  データ() {
    戻る {
      DIFF_CELL_KEY: シンボル("diffCells")、
      COMPLETED_KEY: シンボル("完了")
    };
  },
  計算: {
    完了データ({データグループ、一意のキー、列、DIFF_CELL_KEY、COMPLETED_KEY}) {
      _dataGroup を deepClone します。
      const cacheMap = 新しい Map();
      _dataGroup[0]のconst _rowに対して{
        _row[DIFF_CELL_KEY] = [];
        キャッシュマップを設定します(_row[uniqueKey], _row);
      }
      _dataGroup[1]のconst _rowに対して{
        for (const { prop } 列) {
          (prop === uniqueKey) の場合は続行します。
          定数オリジナル = cacheMap.get(_row[uniqueKey]);
          if (!original) 継続;
          _row[COMPLETED_KEY] = true;
          オリジナル[COMPLETED_KEY] = true;
          _row[prop] !== original[prop] && original[DIFF_CELL_KEY].push(prop);
        }
      }
      this.$_cacheMap = キャッシュマップ;
      _dataGroup を返します。
    }
  },
  メソッド: {
    markRowStyles({行}) {
      戻る (
        !row[this.COMPLETED_KEY] && {
          背景色: "#E1F3D8"
        }
      );
    },
    markCellStyles({ 行, 列 }) {
      const { $_cacheMap、uniqueKey、DIFF_CELL_KEY } = this;
      _cacheRow を $_cacheMap.get(行[一意のキー]);
      戻る (
        _cacheRow &&
        _cacheRow[DIFF_CELL_KEY].includes(列.property) && {
          背景色: "#FDE2E2"
        }
      );
    }
  }
};
</スクリプト>

<style lang="scss" スコープ>
.diff-table-container {
  ディスプレイ: フレックス;
  align-items:flex-start;
  .el-table + .el-table {
    左マージン: 20px;
  }
}
</スタイル>

使用例:

<テンプレート>
  <diff-table :data-group="[oldData, newData]" :columns="tableColumns" />
</テンプレート>

<スクリプト>
「./DiffTable.vue」からDiffTableをインポートします。

エクスポートデフォルト{
  名前: "インデックス",
  コンポーネント:
    差分テーブル
  },
  データ() {
    戻る {
      古いデータ: [
        { id: 1、名前: "zhangsan1"、年齢: 23、住所: "zxczxczxc" }、
        { id: 2、名前: "zhangsan2"、年齢: 23.5、住所: "zxczxczxc" }、
        { id: 3、名前: "zhangsan34"、年齢: 23、住所: "zxczxczxc" }、
        { id: 4、名前: "zhangsan4"、年齢: 23、住所: "zxczxczxc" }、
        { id: 5、名前: "zhangsan5"、年齢: 23、住所: "zxczxczxc" }、
        { id: 6、名前: "zhangsan5"、年齢: 23、住所: "zxczxczxc" }
      ]、
      新しいデータ: [
        { id: 1、名前: "zhangsan1"、年齢: 23、住所: "zxczxczxc" }、
        { id: 2、名前: "zhangsan2"、年齢: 23、住所: "zxczxczxc" }、
        { id: 4、名前: "zhangsan4"、年齢: 23、住所: "住所 住所 住所" }、
        { id: 3、名前: "zhangsan3"、年齢: 23、住所: "zxczxczxc" }、
        { id: 5、名前: "zhangsan5"、年齢: 23、住所: "zxczxczxc" }、
        { id: 7、名前: "zhangsan5"、年齢: 23、住所: "zxczxczxc" }、
        { id: 8、名前: "zhangsan5"、年齢: 23、住所: "zxczxczxc" }
      ]、
      テーブル列: [
        { ラベル: "一意のID"、プロパティ: "ID" },
        { ラベル: "名前"、プロパティ: "名前" },
        { ラベル: "年齢"、プロパティ: "年齢" },
        { ラベル: "アドレス"、プロパティ: "アドレス" }
      ]
    };
  }
};
</スクリプト>

効果プレビュー:

拡張機能TODO:

  • 比較のためにn個のデータグループを構成できる
  • データのグループが 2 つ以上ある場合は、削除されたデータをマークするために DELETE_ROW_KEY を追加する必要があります。
    • ロジックはおおよそ次のようになります。1 つのデータセットにのみ存在するデータは新しく追加され、複数のデータセットに存在するがすべてのデータセットには存在せず、データセットに含まれていないデータは削除済みとしてマークされます。
  • 設定可能な diff スタイル、カスタム diff ルールなど。

要約する

これで、Vue を使用して 2 セットのデータ視覚化コンポーネントの違いを比較する方法に関するこの記事は終了です。Vue を使用して 2 セットのデータの違いを比較する方法に関する関連コンテンツの詳細については、123WORDPRESS.COM で以前の記事を検索するか、次の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

<<:  Windows 上で Nginx+Tomcat クラスタを実装するプロセスの分析

>>:  MysqlクエリJSON結果に関連する関数の概要

推薦する

CSSのマッチング問題を解決する

問題の説明ご存知のとおり、CSS を記述する場合、HTML のクラスの定義または ID の定義に従っ...

mysql-8.0.15-winx64 解凍バージョンのインストールチュートリアルと終了する 3 つの方法

1.公式サイトからダウンロードして解凍する参考: 2. 環境変数を設定するMYSQL_HOMEをMy...

ウェブページを作るときに注意すべき5つのポイント

1. 色合わせの問題<br />Web ページには 3 色以上使用しないでください。そう...

mysql 5.7.18 winx64 無料インストール設定方法

1. ダウンロード2. 減圧3. パス環境変数を追加し、mysqlが配置されているbinディレクトリ...

Windows 上で Nginx+Tomcat クラスタを実装するプロセスの分析

導入: Nginx (エンジン エックスと同じ発音) は、BSD のようなプロトコルに基づいてリリー...

Uniapp は DingTalk スキャンコード ログイン サンプル コードを実装します

UniappにはDingTalk認証ログインがないため、この記事ではDingTalk QRコードログ...

CentOS 6.8 に MySQL 8.0.18 をインストールするチュートリアルの簡単な分析 (RPM 方式)

今日は、CentOS 6.8 サーバーに MySQL 8.0.18 をインストールする方法を記録しま...

Mysqlデータテーブルでワームレプリケーションを使用する方法

簡単に言えば、MySQL ワーム レプリケーションは、クエリされたデータを指定されたデータ テーブル...

MySQL における Decimal 型と Float Double 型の違い (詳細説明)

MySQL には、10 進数などの標準データ型だけでなく、float や double などの非標...

Mysql のフィールドのデータの一部をバッチ置換する (推奨)

MYSQL のフィールドのデータの一部をバッチで置き換えます。具体的な導入は次のとおりです。 1....

CentOSにDockerをインストールする方法

ここでは比較的簡単なインストール方法のみを紹介します。 1. yumを使用してインストールするyum...

CSS マージンの重複とその防止方法

2 つ以上のブロックレベル ボックスの垂直に隣接するエッジが重なり合っています。結果として得られる境...

Angularの親子コンポーネント通信の詳細な説明

目次概要1. 入力および出力プロパティの概要2. 入力属性3. プロパティバインディングは親コンポー...

マウスを動かしたときにセカンダリメニューバーを実装するために HTML+CSS を使用する例

この記事では、マウスを動かしたときにセカンダリ メニュー バーを実装するために HTML+CSS を...

Mysql5.7.14 Linux版のパスワードを忘れた場合の完璧な解決策

/etc/my.confファイルで、[mysqld]の下に次の行を追加します: skip-grant...