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

推薦する

MySQL 1対多関連クエリのページングエラー問題の解決方法

XML価格照会のクエリデータにはリストが含まれているため、コレクションが必要です <結果マップ...

Vue は PDF ファイルのオンライン プレビューを実装します (pdf.js/iframe/embed を使用)

序文現在、私はコースウェア PPT のオンライン プレビューを必要とする高品質のコースに取り組んでい...

mysqlはルートユーザーと一般ユーザーを作成し、機能を変更および削除します。

方法1: SET PASSWORDコマンドを使用する mysql -u ルート mysql> ...

Firefox で Flash を再生するためのオブジェクトとパラメータの書き方

コードをコピーコードは次のとおりです。 <object classid="clsid...

CSS3のtext-fill-colorプロパティの詳細な説明

text-fill-color とは何を意味しますか?文字通りの意味から言えば、「テキストの塗りつぶ...

入力ボックスのプレースホルダーアニメーションと入力検証を実現する純粋なCSS

さらに興味深いコンテンツについては、https://github.com/abc-club/free...

アイデアはDockerプラグインを使用してワンクリックの自動デプロイを実現します

目次環境: 1. Dockerはリモート接続アクセスを可能にするidea dockerプラグインをイ...

HTML チュートリアル: よく使われる HTML タグのコレクション (4)

導入された HTML タグは、必ずしも XHTML 仕様に完全に準拠しているわけではありません。実際...

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

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

nginxサーバーのダウンロード、インストール、使用方法の詳細な説明

ダウンロードhttp://nginx.org/en/download.html解凍ダウンロードしたn...

ミニプログラムは、カスタムのマルチレベル単一選択と複数選択を実装します

この記事では、参考のために、ミニプログラムでカスタムのマルチレベル単一選択および複数選択機能を実装す...

ボタンの 4 つのクリック応答方法の概要

ボタンは頻繁に使用されます。ここでは、イベント処理メソッドを整理し、実装方法が多数あることを発見しま...

Vueはビデオ再生を実装するためにビデオタグを使用します

この記事では、ビデオタグを使用してビデオ再生を実装するVueの具体的なコードを参考までに共有します。...

MySQL サービスに iptables ファイアウォール ポリシーを追加するためのソリューション

MySQL データベースが Centos7 システムにインストールされており、オペレーティング シス...

制限およびオフセット ページング シナリオを使用すると速度が遅くなるのはなぜですか?

質問から始めましょう5 年前、私が Tencent にいたとき、ページング シナリオでは MySQL...