スケーラブルな列の完全な例を実現するための Ant 設計 Vue テーブル

スケーラブルな列の完全な例を実現するための Ant 設計 Vue テーブル

ant-design-vue テーブルのスケーラブルな列の問題に対する完璧なソリューション。固定列とマルチレベル ヘッダーでスケーラブルな列を実現します。

公式サイトに例が載っていたので、これは簡単に使えるだろうと思いました。しかし、公式サイトをあまり信用することはできません。公式サイトでは最も基本的なものしか提供されておらず、私たちの通常の使用シナリオは、固定列、固定ヘッダー、組み込みチェックボックス列、マルチレベルヘッダーなど、はるかに複雑な場合が多いです。こうした状況に対応するには、独自のものを開発する必要があることがよくあります。

1. まず、蒋介石の公式例を真似したのですが、引きずり出すことができませんでした。

公式のものと比較したところ、CSSが異なっていたため、最初の変更を加えました。スタイルのインラインスタイルには独自のtranslate属性があるため、right: 0を直接削除し、left -5のみにしました。高さを100%に設定しました。

.resize-table-th {
    位置: 相対的;
    .table-ドラッグ可能なハンドル {
      高さ: 100% !重要;
      下部: 0;
      左: -5px !重要;
      カーソル: col-resize;
      タッチアクション: なし;
      位置: 絶対;
    }
  }

2. 今回は、ドラッグするたびに translate 属性がリアルタイムで変化しますが、セルは広くなったり移動したりしないことがわかります。

そこで、要素を再度確認したところ、 th の幅は変化していましたが、 colGroup の width 属性は変化していませんでした。そこで、対応する colGroup 子要素 col を探し始めました。ついにそれを見つけたので、ドラッグしながら colGroup の col の width 属性を変更しました。こうすることで、変更を追跡できます。

3. 次に、列とヘッダーが固定されている場合にストレッチするとバグが発生することがわかりました。

コードを見ると、固定列や固定ヘッダーの場合、thead と tbody は実際には別のテーブルにあることがわかりました。このとき、col を測定して幅を変更するには、すべての colGroups を見つける必要があります。これは固定ヘッダーの伸縮を処理します。ただし、固定列の場合には、CSS を別途設定し、table-fixed-left を見つけて幅をリセットする必要があります。

ここにコードがあります

現在の th に従って、どの子ノード th が親要素であるかを判断し、それが colGroup のどの col ノードに対応するかを決定します。

定数 loopDom = ss => {
  ss.previousSibling !== null の場合 {
    thDomIndex++;
    loopDom(ss.previousSibling);
  }
};

固定列の幅をリセットします(左フロートのみ処理します)

関数 resetFixedColumns(幅) {
  const fixedHead = document.querySelector(".ant-table-fixed-left .ant-table-header");
  const fixedBody = document.querySelector(".ant-table-fixed-left .ant-table-body-outer .ant-table-fixed");
  if (固定ヘッド) {
    fixedHead.style.width = 幅 + "px";
    fixedBody.style.width = 幅 + "px";
  }
}

複数レベルのヘッダー拡張列の問題を解決する

配列を再帰的に走査して幅を取得する

getDraggingMap(tbCols、ドラッグマップ) {
      tbCols.forEach(列 => {
        if (col.children) {
          this.getDraggingMap(col.children, draggingMap);
        } それ以外 {
          const key = col.dataIndex || col.key; //テーブルデータにはこれらの 2 つの属性が必要です draggingMap[key] = col.width || 0;
        }
      });
    },

配列を再帰的に走査し、現在の列を取得します(この再帰は本当に面倒です。再帰の書き方についてどう感じているかはわかりません)

// マルチレベルヘッダーの処理 getRenderCoL(key, tbCols) {
      結果 = "" とします。
      this._.forEach(tbCols, 項目 => {
        if (item.children) {
          結果 = this.getRenderCoL(キー、item.children);
          !結果を返します。
        } それ以外 {
          const k = item.dataIndex || item.key;
          if (k === キー) {
            結果 = アイテム;
            false を返します。
          }
        }
      });
      結果を返します。
    }

配列を再帰的にトラバースして、マルチレベルヘッダー操作列のインデックスを取得します(再帰も耐えられません。最初は最後のレンターンが欠落しており、間違った実行が続きます。再帰のシャドウ領域は無限です)

 定数 loopDom = (cols, col) => {
          タグを true にします。
          this._.forEach(cols, co => {
            co.dataIndex == col.dataIndexの場合{
              thDomIndex++;
              タグ = false;
              戻りタグ;
            }
            if (co.children) {
              タグ = loopDom(co.children, col);
              戻りタグ;
            } それ以外 {
              thDomIndex++;
            }
          });
          戻りタグ;
        };

完全なコードはこちら

これは、テーブルメインファイルをミックスイン経由で導入するjsファイルです。テーブルは

:components="ドラッグ(列キー)"
//mixins/tableDragResize.js
「vue」からVueをインポートします。
「vue-draggable-resizable」から VueDraggableResizable をインポートします。
Vue.component("vue-draggable-resizable", VueDraggableResizable);

エクスポートデフォルト{
  データ() {
    戻る {
      最大レベル: 1
    };
  },
  メソッド: {
    ドラッグ(列) {
      戻る {
        ヘッダー: {
          セル: this.initDrag(列)
        }
      };
    },
    /**
     * @param { テーブル列 } tbCols
     */
    initDrag(tbCols) {
      ドラッグマップを {} にします。
      this.getDraggingMap(tbCols, draggingMap, 1);
      draggingState を Vue.observable(draggingMap) にします。
      戻り値 (h, props, children) => {
        thDomIndex = 0 とします。
        const { キー、...restProps } = props;
        col = {} とします。
        // マルチレベル ヘッダーの処理 col = this.getRenderCoL(key, tbCols);
        列の幅が等しい場合
          //ここで、テーブル データには width 属性が必要です。そうでない場合、次のドラッグは実行されません。 return <th {...restProps}>{children}</th>;
        }
        定数onDrag = x => {
          列の幅 = Math.max(x, 1);
          ドラッグ状態[キー] = col.width;
          ドメインインデックス = 0;
          loopDom(tbCols, col);
          チェックありの場合
            ドメインインデックス--;
          }
          colgroup を document.querySelectorAll("colgroup") とします。
          colgroup.forEach(要素 => {
            childCol を Element.children とします。
            childCol[thDomIndex]の場合、childCol[thDomIndex].style.width = col.width + "px";
          });
          this.resetFixedColumns(列の幅);
        };
        定数 loopDom = (cols, col) => {
          タグを true にします。
          this._.forEach(cols, co => {
            co.dataIndex == col.dataIndexの場合{
              thDomIndex++;
              タグ = false;
              戻りタグ;
            }
            if (co.children) {
              タグ = loopDom(co.children, col);
              戻りタグ;
            } それ以外 {
              thDomIndex++;
            }
          });
          戻りタグ;
        };
        定数onDragstop = () => {};

        戻る (
          <th {...restProps} width={draggingState[key]} class="resize-table-th" dataIndex={col.key}>
            {子供たち}
            <vue-ドラッグ可能-サイズ変更可能
              キー={col.dataIndex || col.key}
              クラス="テーブルドラッグ可能ハンドル"
              w={20}
              h = {this.getResizableHandler(col)}
              x={ドラッグ状態[キー]}
              100 は
              軸="x"
              ドラッグ可能={true}
              サイズ変更可能={false}
              onDragging={onDrag}
              onDragstop={onDragstop}
            </vue-ドラッグ可能-サイズ変更可能>
          </th>
        );
      };
    },
    getResizableHandler(col) {
      // baseH = thDom.getBoundingClientRect().height; とします。
      size を this.cellsize とします。this.cellsize : this.attrBute.cellsize;
      baseH を size == "middle" ? 47 とします : size == "small" ? 39 : 55;
      col.isEndNode の場合、baseH * col.nodeLevel を返します。
      そうでない場合 (col.leafNode && col.nodeLevel < this.maxLevel) {
        baseH * this.maxLevel を返します。
      } それ以外の場合は baseH を返します。
    },
    固定列幅をリセットする(幅)
      const fixedHead = document.querySelector(".ant-table-fixed-left .ant-table-header");
      const fixedBody = document.querySelector(".ant-table-fixed-left .ant-table-body-outer .ant-table-fixed");
      if (固定ヘッド) {
        fixedHead.style.width = 幅 + "px";
        fixedBody.style.width = 幅 + "px";
      }
    },
    getDraggingMap(tbCols、draggingMap、nodeLevel) {
      tbCols.forEach((列、インデックス) => {
        col.nodeLevel = ノードレベル;
        col.isEndNode = インデックス == tbCols.length - 1;
        this.maxLevel = Math.max(this.maxLevel、ノードレベル);
        if (col.children) {
          col.leafNode = false;
          this.getDraggingMap(col.children, draggingMap, nodeLevel + 1);
        } それ以外 {
          col.leafNode = true;
          const key = col.dataIndex || col.key; //テーブルデータにはこれらの 2 つの属性が必要です draggingMap[key] = col.width || 0;
        }
      });
    },
    getRenderCoL(キー、tbCols) {
      結果 = "" とします。
      this._.forEach(tbCols, 項目 => {
        if (item.children) {
          結果 = this.getRenderCoL(キー、item.children);
          !結果を返します。
        } それ以外 {
          const k = item.dataIndex || item.key;
          if (k === キー) {
            結果 = アイテム;
            false を返します。
          }
        }
      });
      結果を返します。
    }
  }
};

追記 マルチレベルテーブルヘッダーの拡張列に対する完璧なソリューション 元のgetDraggingMapメソッドを変更し、nodeLevelレベルを追加します。isEndNodeはカバーレベルの下の最後のノードであり、this.maxLevelは最大レベルを記録します

getDraggingMap(tbCols、draggingMap、nodeLevel) {
tbCols.forEach((列、インデックス) => {
col.nodeLevel = ノードレベル;
col.isEndNode = インデックス == tbCols.length - 1;
this.maxLevel = Math.max(this.maxLevel、ノードレベル);
if (col.children) {
col.leafNode = false;
this.getDraggingMap(col.children, draggingMap, nodeLevel + 1);
} それ以外 {
col.leafNode = true;
const key = col.dataIndex || col.key; //テーブルデータにはこれらの 2 つの属性が必要です draggingMap[key] = col.width || 0;
}
});
},

テーブルドラッグハンドルの高さを処理するメソッドを追加します

画像を表示

ここに画像の説明を挿入

ドラッグ可能な領域は赤い領域です。この効果を実現するには、次の処理が必要です。

まず、CSS の高さを削除します: 100%;
次にレンダリング時にコンポーネントの高さを次のように設定します。

h = {this.getResizableHandler(col)}

サイズはテーブルのサイズです

getResizableHandler(col) {
      // baseH = thDom.getBoundingClientRect().height; とします。
      size を this.cellsize とします。this.cellsize : this.attrBute.cellsize;
      baseH を size == "middle" ? 47 とします : size == "small" ? 39 : 55;
      col.isEndNode の場合、baseH * col.nodeLevel を返します。
      そうでない場合 (col.leafNode && col.nodeLevel < this.maxLevel) {
        baseH * this.maxLevel を返します。
      } それ以外の場合は baseH を返します。
    },

終わり

上記は、スケーラブルな列を実現するための ant design vue table の詳細です。ant design vue table scalable columns の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • vue パブリック リスト選択コンポーネント、Vant-UI スタイルの参照
  • Ant Design Vue テーブル列の超長い表示...およびプロンプトの例の追加
  • Vue+vant が商品リストの一括カウントダウン機能を実現

<<:  Centos7 に yum 経由で MySQL をインストールする方法

>>:  Apache Tika を使用してファイルが破損しているかどうかを検出する方法

推薦する

MySQL インストール プロンプト「詳細なヘルプについては NET HELPMSG 3534 と入力してください」の解決方法

今日、MySQL をインストールすると次のエラー メッセージが表示されます。 かなり長い時間ネットで...

Vue Element フロントエンドアプリケーション開発開発環境の準備

目次概要1. 必要なソフトウェア環境を開発する1) VSコードのインストール2) ノード開発環境をイ...

最新バージョンMySQL5.7.19 解凍版インストールガイド

MySQL バージョン: MySQL Community Edition (GPL) ------ ...

MySQL データベースのインデックスとトランザクション

目次1. 索引1.1 コンセプト1.2 機能1.3 索引作成の原則1.3.1 ディスクアクセス回数を...

MySQL 8.0.22 の最新バージョンのダウンロードとインストールの超詳細なチュートリアル (Windows 64 ビット)

目次序文1. 公式サイトからMySQL 8.0.22をダウンロードする2. 環境変数を設定する3. ...

MySQL が「operate_time」エラーのデフォルト値が無効であると報告する問題を解決する

データベースでcreate tableステートメントを実行する テーブル `sys_acl` を作成...

Linuxにおけるselinuxの基本設定チュートリアルの詳細な説明

selinux ( Security-Enhanced Linux)は、Linux カーネル モジュ...

Linux で NFS ファイル共有サーバーを構築するための詳細な手順

Linux が NFS サーバーを構築異なるオペレーティング システム間でデータを共有するために、通...

MySQLとRedisでセカンダリキャッシュを実装する方法の詳細な説明

Redis の紹介Redis は完全にオープンソースで無料であり、BSD プロトコルに準拠しており、...

Linux+ApacheサーバURLの大文字と小文字の区別の問題を解決する

今日、問題が発生しました。ブラウザのアドレスバーにURLアドレスを入力する際、ページを正常にアクセス...

MySQLサービスを削除する具体的な方法

MySQLは次のエラーを表示します「コントロール パネル -> 管理ツール -> サービ...

MySQL パーティション テーブルの基本入門チュートリアル

序文最近のプロジェクトでは、大量のデータを保存する必要があり、このデータには有効期限があります。クエ...

シェアしたい絶妙なApple風無料アイコン素材18セット

Apple マグカップのアイコンと追加機能 HD ストレージボックス – アドオンパックセイバースノ...

Linux でソースインストールされたパッケージを簡単に削除する方法

ステップ1: Stowをインストールするこの例では CentOS を使用しているため、拡張 EPEL...

水平ヒストグラムを作成するための MySQL ソリューション

序文ヒストグラムは、RDBMS によって提供される基本的な統計情報です。最も一般的に使用されるのは、...