vueはel-tableの列幅の適応を完璧に実現します

vueはel-tableの列幅の適応を完璧に実現します

背景

Element UI は、PC で人気の Vue.js UI フレームワークです。そのコンポーネント ライブラリは、基本的にほとんどの一般的なビジネス ニーズを満たすことができます。しかし、場合によっては、コンポーネント自体では満たせない、高度にカスタマイズされた要件が存在することがあります。最近、プロジェクトでこれに遭遇しました。

多くのページではテーブル コンポーネント el-table が必要です。 el-table-column に幅が指定されていない場合は、デフォルトで残りの列に均等に分散されます。列数が多い場合、el-table の幅がコンテナーに制限されると、セル内のコンテンツが折り返されます。行の折り返しを強制しません。コンテンツはセル内でスクロールするか、オーバーフローするか、切り捨てられます。

製品の望ましい効果は、コンテンツが 1 行に表示され、列の間隔が一定で、テーブルがコンテナーを超えて水平スクロールを可能にすることです。 el-table-column は固定幅の設定をサポートしており、コンテンツの幅が予測可能な場合にこの要件を満たすことができます。問題は、列の幅をコンテンツの幅に合わせて動的に調整する方法です。公式ドキュメントにはそのようなオプションは見つかりませんでした。おそらく、コンポーネント自体がサポートしていないためでしょう。

技術的ソリューション

そこで、コンテンツの幅を動的に計算するソリューションを考えました。このアイデアについてはオンラインで言及している人もいますが、そのアプローチは、コンテンツ内の文字数に基づいて幅を計算するというものです。このアプローチにはいくつかの制限があります。

  • コンテンツはテキストである必要があります
  • 文字によって幅が異なり、決済結果が十分に正確ではない
  • レンダリング前にデータを操作する必要があり、分離には役立たない

私は別のアイデアを採用しました。それは、実際にレンダリングされた DOM 要素の幅に基づいてコンテンツの幅を動的に計算することで、上記の 3 つの問題を解決できるというものです。

具体的にはどうすればいいのでしょうか?レンダリングされた DOM 要素を見ると、el-table のヘッダーとコンテンツはそれぞれネイティブ テーブルを使用し、各列の幅は colgroup によって設定されていることがわかります。ここから始めましょう。col の name 属性値は、対応する td の class 値と一致しています。このようにして、対応する列のすべてのセルをトラバースし、幅が最大のセルを見つけ、そのコンテンツ幅に余白を加えたものを列の幅として使用できます。

具体的な実装

コンテンツの幅を計算するには?これは比較的重要なステップです。レンダリング後、各セルには .cell クラスがあり、white-space: nowrap; overflow: auto; で改行を許可しないように設定されています。制限を超えた場合はコンテンツをスクロールでき、実際のコンテンツの幅を計算するために display: inline-block; が設定されています。このように、最終的な幅は .cell 要素の scrollWidth プロパティを通じて取得できます。

関数adjustColumnWidth(テーブル) {
  const colgroup = table.querySelector("colgroup");
  const colDefs = [...colgroup.querySelectorAll("col")];
  colDefs.forEach((col) => {
    const clsName = col.getAttribute("名前");
    定数セル = [
      ...table.querySelectorAll(`td.${clsName}`)、
      ...table.querySelectorAll(`th.${clsName}`)、
    ];
    // "leave-alone"クラスの列を無視する if (cells[0]?.classList?.contains?.("leave-alone")) {
      戻る;
    }
    定数widthList = cells.map((el) => {
      el.querySelector(".cell")?.scrollWidth || 0 を返します。
    });
    const max = Math.max(...widthList);
    定数パディング = 32;
    table.querySelectorAll(`col[name=${clsName}]`).forEach((el) => {
      el.setAttribute("幅", 最大値 + パディング);
    });
  });
}

途中の探索プロセスはかなり面倒ですが、最終的なコード実装は非常に簡潔です。列幅の計算はいつ実行されますか?当然、コンポーネントのレンダリングが完了した後です。再利用を容易にするために、Vue カスタム ディレクティブ アプローチを採用しました。

Vue.directive("fit-columns", {
  アップデート() {}、
  バインド() {},
  挿入(el) {
    タイムアウトを設定する(() => {
      列幅を調整します(el);
    }, 300);
  },
  コンポーネントが更新されました(el) {
    el.classList.add("r-table");
    タイムアウトを設定する(() => {
      列幅を調整します(el);
    }, 300);
  },
  アンバインド() {},
});

さらに、v-fit-columns という Vue プラグインをカプセル化しました。これは npm リポジトリに公開されており、直接インストールして使用できます。
インストール:

npm をインストール v-fit-columns --save

輸入:

'vue' から Vue をインポートします。
'v-fit-columns' からプラグインをインポートします。
Vue.use(プラグイン);

使用:

<el-table v-fit-columns>
  <el-table-column label="No." type="index" class-name="leave-alone"></el-table-column>
  <el-table-column label="名前" prop="名前"></el-table-column>
  <el-table-column label="年齢" prop="年齢"></el-table-column>
</el-table>

ソースコード リポジトリはこちらです: https://github.com/kaysonli/v-fit-columns。ぜひコメントやスターをお願いします!

要約する

このソリューションは、ある意味ハックであり、要件を満たすことのみに関心があります。レンダリング後にわずかなフラッシュが発生するなど、他の側面でいくつかの欠陥がある可能性があります (幅を再調整する必要があり、リフローが発生するため)。しかし、最終的な効果から判断すると、かなり満足のいくものです。

上記は、vue の el-table 列幅適応の完璧な実装の詳細な内容です。vue の el-table 列幅適応の実装の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Vueはel-tableを使用して円形カルーセルデータリストを実装します
  • VUE2.0+ElementUI2.0 テーブル el-table loop 動的列レンダリングの書き方を詳しく解説
  • vue+Element のテーブルは編集可能です (ドロップダウン ボックスを選択)
  • Vueはel-tableを使用してループし、テーブルを生成します。

<<:  Linuxサーバーのファイアウォールを変更してポートへのリモートアクセスを許可する方法

>>:  Windows 10 + mysql 8.0.11 zipインストールチュートリアルの詳細

推薦する

tomcat+nginx を使用してマルチアプリケーション デプロイメントを実装するためのサンプル コード

目次マルチアプリケーションの展開1-Tomcat 構成1.1- プロジェクト構成1.2-サービス構成...

InnoDBのインデックスページ構造、挿入バッファ、適応ハッシュインデックスについての簡単な説明

InnoDB インデックスの物理構造すべての InnoDB インデックスは Btree インデックス...

XHTML Web ページ チュートリアル

この記事は主に、初心者に XHTML の基本的な知識と、XHTML と HTML の違いを理解しても...

JavaScript の基礎: エラーキャプチャメカニズム

目次序文エラーオブジェクト投げる試して…捕まえて…最後に最終ルールトライ/キャッチパフォーマンスウィ...

現在のMySQL接続数を表示する方法の詳細な説明

1. 現在のすべての接続の詳細情報を表示します。 ./mysqladmin -uadmin -p -...

Tomcat は親の委任メカニズムを破壊して Web アプリケーションの分離を実現します。

目次Tomcat クラスローダー階層WebAppクラスローダー共有クラスローダーカタリナクラスローダ...

JSONP クロスドメインシミュレーション Baidu 検索

目次1. JSONPとは何か2. JSONPクロスドメインリクエスト3. Baidu検索をシミュレー...

win2008R2 64 ビット システムでの mysql5.7.17 のインストールと構成の例

123WORDPRESS.COM では、さまざまな環境での MYSQL の他のバージョンのインストー...

Vue Element Sortablejs を使用してテーブル列をドラッグする詳細な説明

1. css: ドラッグテーブル.css @charset "UTF-8"; ....

Mysql の一般的なベンチマーク コマンドの概要

mysqlslap共通パラメータの説明–auto-generate-sql システムはテスト用のSQ...

開発効率の向上に役立つ 56 個の実用的な JavaScript ツール関数

目次1. デジタルオペレーション(1)指定された範囲内で乱数を生成する2. 配列操作(1)配列の順序...

jQueryは要素を追加した後に元のイベントが実行されない問題を解決します

まずエラーコードを見てみましょう。 html: <テーブルボーダー="1"...

Vueは製品の拡大鏡効果を実現します

この記事の例では、製品の拡大鏡効果を実現するためのVueの具体的なコードを共有しています。具体的な内...

MySQL クエリ データベース容量方法手順

すべてのデータベースの合計サイズを照会する方法は次のとおりです。 mysql> informa...

Centos は chrony 時間同期サーバー プロセス図を構築します

私の環境: 3 centos7.5 1804マスター 192.168.100.140ノード1 192...