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結果に関連する関数の概要

推薦する

Docker基盤技術の適用に関する詳細な説明 名前空間Cgroup

Docker の基盤技術: Docker の基盤となる 2 つのコア テクノロジーは、名前空間とコ...

MySQL 5.7.23 解凍バージョンのインストールチュートリアル(画像とテキスト付き)

毎回インストールチュートリアルを探すのは面倒なので、後で確認できるように手順をバックアップします。解...

Dockerイメージ送信コマンドcommitの動作原理と使い方の詳細な説明

ローカルでコンテナを作成した後、このコンテナに基づいてローカル イメージを作成し、このイメージを D...

MySQL 5.7 の /etc/my.cnf パラメータの紹介

以下は、mysql 5.7 の /etc/my.cnf の一般的なパラメータの一部です。これらを自分...

ドラッグ位置プレビューを実装するネイティブJS

この記事では、要素をドラッグするときにプレビューを追加する小さなデモを紹介します。効果は次のとおりで...

nginx ベースのブラウザネゴシエーションキャッシュプロセスの詳細な説明

この記事は主に、nginx に基づいてブラウザネゴシエーションキャッシュを設定する詳細なプロセスを紹...

リモート接続を許可するようにMySQLを変更する方法

MySQLリモート接続の問題に関しては、会社で働いているときに誰かのコンピュータに保存されているMy...

Docker コンテナ データ ボリュームの名前付きマウントと匿名マウントの問題

目次コンテナデータボリュームとはコンテナ データ ボリュームが必要なのはなぜですか?使用データボリュ...

Docker ベースの Selenium 分散環境の構築

1.画像をダウンロードするdocker pull selenium/hub docker pull ...

タグのターゲットリンクを iframe に向ける方法

コードをコピーコードは次のとおりです。 <iframe id="myFrameId&...

Vue はデータの変更をどのように追跡しますか?

目次背景例誤解 - コールスタックを表示するためにウォッチでブレークポイントを設定する正しいアプロー...

インスタンス化されたオブジェクトパラメータによるMySQLクエリ例の説明

この記事では、オブジェクト パラメータをインスタンス化して MySQL でデータをクエリする方法を紹...

Vueはランニングライトのシンプルな効果を実現

この記事では、マーキーのシンプルな効果を実現するためのVueの具体的なコードを参考までに共有します。...

href をクリックした後にページがジャンプしないようにするための空のリンクの正しい書き方 # 問題

リンクを使用する必要がある場合もありますが、リンクする必要はありません。onclick イベントを処...