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インストールチュートリアルの詳細

推薦する

Docker を使用した nGrinder パフォーマンス テスト プラットフォームの導入プロセスの分析

nGrinderとは何ですか? nGrinder は、スクリプトの作成、テストの実行、監視、結果レポ...

CSS の 6 つの重要なセレクター (3 秒で覚える)

出典: https://blog.csdn.net/qq_44761243/article/deta...

MySQLテーブルの内容の変更を監視し、MySQL binlogを有効にする

序文binlog は、MySQL のすべての追加、削除、および変更ステートメントを記録するバイナリ ...

JavaScript でプロパティハイジャックを実装する方法 defineProperty

目次序文記述子getとsetの詳細な説明オブジェクトの属性の乗っ取りオブジェクトのすべてのプロパティ...

CentOS7 構成 Alibaba Cloud yum ソースメソッドコード

Centos yumフォルダを開くコマンドcd /etc/yum.repos.d/を入力します。 w...

ウェブサイトのカラースキーム ウェブサイトに適した色の選択

色はウェブサイト訪問者に影響を与えますか?数年前までは、ウェブサイトはまだ贅沢品でしたが、今ではほと...

MYSQL の 10 の典型的な最適化ケースとシナリオ

目次1. SQL最適化の一般的な手順1. SQL実行計画の分析を説明する2. プロフィール分析を表示...

HTMLチェックボックス説明テキストをクリックして状態を選択/チェック解除します

Web 開発では、チェックボックスは小さく、ユーザーにとって操作があまり便利ではないため、ユーザーが...

Dockerコンテナのログ分析

コンテナログを表示するまず、 docker run -it --rm -d -p 80:80 ngi...

Vue-CLI マルチページディレクトリパッケージ化手順の記録

ページディレクトリ構造 デフォルトの HTML テンプレート ファイル public/index.h...

vue3 でブロック崩しゲームを開発する方法をステップバイステップで教えます

序文vue3 を使った例をいくつか書いてみましたが、Vue3 のコンポジション API はよく設計さ...

Linuxアカウントファイル制御管理の詳細な手順

Linux システムでは、ユーザーが手動で作成したさまざまなアカウントに加えて、システムまたはプログ...

dockerコマンドの使用にはsudoは必要ありません

docker デーモンは通常の TCP ポートではなくホストの Unix ソケットにバインドする必要...

MySQL シリーズ 6 のユーザーと認証

目次チュートリアルシリーズ1. ユーザー管理1. ユーザーアカウント2. アカウントの追加と削除3....

Linux (Centos7) に mysql8.0.18 をインストールするチュートリアル図

1 インストールリソースパッケージmysql-8.0.18-1.el7.x86_64.rpm-bun...