ElementUI el-select の過剰なデータに対する解決策についての簡単な説明

ElementUI el-select の過剰なデータに対する解決策についての簡単な説明

1. シナリオの説明

これまでにこのような経験をしたことがあるかどうかはわかりません。ドロップダウン ボックスには多くのオプションがあり、数万、あるいはそれ以上のオプションがあります。このとき、すべてのデータをドロップダウン ボックスに入れてレンダリングすると、ブラウザーがフリーズし、エクスペリエンスが特に悪くなります。

element-ui の select にはリモート検索をサポートするリモートメソッドがあると言うユーザーもいるかもしれません。サーバーにそれをサポートするように依頼するだけではだめでしょうか? もちろん、これは解決策です。しかし、この方法は適用できない場合もあります

(1) サーバー側のデータが計算後に返されることがあり、その戻りがあまり速くない場合があるため、エクスペリエンスはあまり良くありません。 (2) データが数千個しかない場合があり、すべてをレンダリングするのは適切ではありません。インターフェイスを低く保つのはあまり良くありません。 (3) フロントエンドだけで解決できますか? 解決できれば、サーバーの作業と負荷が軽減されるのではないでしょうか?

2. 解決策

1) セグメント化された読み込み: ドロップダウン項目は読み込まれません。ドロップダウン ボックスをクリックすると、読み込まれます。この時点で、すべてのオプションが読み込まれます。この状況は、読み込みが遅い場合にのみ当てはまります。オプションをドロップダウンする前に、クリックして読み込む必要があります。エクスペリエンスは平均的です。
2) ヒント: element-uiのselectにはfilter-methodメソッドがあり、これを使ってドロップダウン項目をフィルタリングすることができます。ユーザーを選択するためのドロップダウンボックスがあるとします。

<el-選択
  v-model="ユーザーID"
  フィルター可能
  :filter-method="ユーザーフィルター"
  クリア可能>
  <el-オプション
    v-for="userList 内の項目"
    :key="item.userId"
    :label="item.ユーザー名"
    :value="item.userId"
  </el-option>
</el-select>
ユーザーフィルター(クエリ = '') {
  arr = this.allUserList.filter((item) => { とします。
    item.username.includes(クエリ) || item.userId.includes(クエリ) を返します
  })
  (arr.length > 50)の場合{
    this.userList = arr.slice(0, 50)
  } それ以外 {
    this.userList = arr
  }
},
getUserWhiteList() {
  HttpRequest.post("/api/admin/community/getUserWhiteList").then(
    レスポンス => {
      this.allUserList = 応答データリスト;
      this.userFilter()
    }
  );
},

上記のように、バックグラウンドからユーザー リストを取得します。独自のフィルタリングを行った後、一度にレンダリングされるデータは 50 個のみです。データの量に関係なく、変数がサポートされ、メモリが消費されます。もちろん、データが増えるほど配列の走査は遅くなりますが、影響はほとんどありません。
名前をフィルタリングするだけでなく、設定した項目を最適化することもできます。上記のコードも適切に最適化できます。配列の長さが 50 項目を超えた場合にのみ、トラバースを停止します。

オプションが多すぎる el-select コンポーネントの解決策

ビジネスシナリオ

el-select コンポーネントを使用する場合、オプションが多すぎると、次のようなデメリットが生じます。

このページでは、多数の el-option ノードがレンダリングされるため、ページがフリーズしたり、フリーズしたりして、ユーザー エクスペリエンスが非常に低下します。
選択できるアイテムが多すぎて、見つけるのが困難です。

今回遭遇したシナリオは、選択肢の数が6~9千個という状況でした。

解決

ページレンダリングの全体オプションから固定項目の小さなオプション(renderOption)を取り出し、
filter-method メソッドは検索フィルタリングを実行し、検索中にフィルタ結果で renderOption を更新します。

コード実装以下はVueのコンポーネントカプセル化です

<テンプレート>
    <el-選択
        クラス="yt-select"
        v-model="currValue"
        フィルター可能
        v-bind="$attrs"
        :filter-method="ユーザーフィルター"
        :disabled="無効"
        :clearable="クリア可能"
        @change="変更"
    >
        <el-オプション
            v-for="renderOption 内のオプション"
            :key="オプション.値"
            :value="オプションの値"
            :label="オプション.ラベル"
        >{{ オプション.ラベル }}</el-option>
    </el-select>
</テンプレート>

<スクリプト>

エクスポートデフォルト{
    名前: 'easy-select',
    小道具: {
        価値: {
            タイプ: [文字列、数値],
            デフォルト: ''
        },
        最大: {
            タイプ: 数値、
            デフォルト: 30
        },
        無効:
            タイプ: ブール値、
            デフォルト: false
        },
        クリア可能: {
            タイプ: ブール値、
            デフォルト: true
        },
        オプション:
            タイプ: 配列、
            デフォルト: () => []
        }
    },
    データ () {
        戻る {
            レンダリングオプション: []
        }
    },
    計算: {
        通貨値: {
            得る () {
                this.value を返します || ''
            },
            設定(値) {
                this.$emit('入力', 値)
            }
        }
    },
    時計:
        価値 () {
            this.addValueOptions()
        },
        オプション:
            ハンドラー(V){
                この.init()
            },
            深い: 本当
        }
    },
    作成された(){
        この.init()
    },
    メソッド: {
        非同期初期化(){
            this.userFilter()
            this.addValueOptions()
        },
        値オプションを追加します () {
            if (this.currValue) {
                let target = this.options.find((item) => { // 大きなオプションから現在の項目を検索します return item.value === this.currValue
                })
                if (target) { // 現在のアイテムを小さいオプションと比較し、そうでない場合は追加します if (this.renderOption.every(item => item.value !== target.value)) {
                        this.renderOption.unshift(ターゲット)
                    }
                }
            }
        },
        addFilterOptions (ラベル) {
         // 入力を検索するたびに、完全一致がある場合は、アイテムが renderOption にあることを確認します。let target = this.options.find((item) => { // 大きなオプションから現在のアイテムを検索します。return item.label === label
            })
            if (target) { // 現在のアイテムを小さいオプションと比較し、そうでない場合は追加します if (this.renderOption.every(item => item.label !== target.label)) {
                    this.renderOption.unshift(ターゲット)
                }
            }
        },
        ユーザーフィルター (クエリ = '') {
            arr = this.options.filter((item) => { とします。
                item.label.includes(クエリ) || item.value.includes(クエリ) を返します
            })
            (arr.length>this.max)の場合{
                this.renderOption = arr.slice(0, this.max)
                this.addFilterOptions(クエリ)
            } それ以外 {
                this.renderOption = arr
            }
        },
        変更(値){
            this.$emit('change', 値)
            if (!value) { // 単一選択のクリアオプションを初期化します this.userFilter()
            }
        }
    }
}
</スクリプト>

予防

  • 値を初期化して変更するときは、値に対応する特定の項目を見つけてrenderOptionsに追加する必要があります。
  • 検索時に、フィルタリングされた n 個のデータ項目のいずれにも、ユーザーが探している特定の項目が含まれていない可能性があります。そのため、フィルタリング時には正確な検索が必要であり、一致する項目が renderOptions ヘッダーに配置されます。

ElementUI el-select のデータ量が多すぎる問題の解決方法についての記事はこれで終わりです。ElementUI el-select のデータ量が多すぎる問題の詳細については、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • vue elementUI が el-select を使用するときに変更イベントがトリガーされる問題を解決する
  • element-ui のドロップダウン複数選択ボックス el-select を使用するときにデフォルト値を削除できない問題を解決します。
  • Vue + Element-ui のドロップダウンボックス el-select の追加パラメータを取得する詳細な説明
  • Element-ui リモート検索コンポーネント el-select コンポーネント化された実装コードをプロジェクト内
  • element-ui の el-select のデフォルト選択の問題の詳細な説明
  • vue2.0 element-ui の el-select セレクターは選択されたコンテンツを表示できません (解決策)

<<:  Ubuntu 20.04にROS Noeticをインストールする方法

>>:  操作タイムアウトがないときにMySQLサーバーがアクティブに切断される問題を解決します

推薦する

MySQL 5.7.16 のインストールと設定方法のグラフィック チュートリアル (Ubuntu 16.04)

Ubuntu 16.04 に MySQL 5.7 をインストールするにはどうすればいいですか?メイ...

mysql maxとwhere間の実行問題の概要

mysql maxとwhereの間の実行の問題SQLを実行します: テーブル「grades」を作成し...

IE6/7 は混乱するだろう: 空のテキスト ノードの高さの問題

序文: ietester でドキュメント コードを表示するには、debugbar を使用します。すべ...

Vueページジャンプの実装方法

1. this.$router.push() 1. ビュー <テンプレート> <d...

Vueデータ監視の原理の詳細な説明

<本文> <div id="ルート"> <h1&...

mysqlはコンマに基づいてデータ行を複数の行に分割します

目次分離効果コマンドラインの説明関与する機能分離効果-- 別居前1,2,3,4 -- 別居後1 2 ...

VMware Workstation16 と Navicat リモート接続での Centos7 での MySQL8.0 インストール プロセス

目次1. CentOS7+MySQL8.0、yumソースインストール2. MySQLにログインしてパ...

MySQL UPDATE ステートメントの「典型的な」落とし穴

目次1. 問題のあるSQL文たとえば、次の図のような質問をした人がいました。 問題は次のように要約で...

Dockerコンテナの接続と通信の実装

ポート マッピングは、Docker を別のコンテナーに接続する唯一の方法ではありません。 Docke...

MySQL データベースのホットスタンバイにおける問題点の分析

以前、MySQL データベースのデュアルマシン ホット スタンバイの設定方法を紹介しました。ご興味の...

JavaScript の組み込みオブジェクト 数学と文字列の詳細な説明

目次数学オブジェクト共通プロパティ一般的な方法Math.random()文字列メソッド長さプロパティ...

IntelliJ IDEA に Docker プラグインをインストールする詳細な手順 (2018 バージョン)

目次1. 開発環境2. dockerプラグインをインストールする1. アイデアのインストール2. イ...

Vue を通じて QR コードスキャン機能を実装する

ヒントこのプラグインは https プロトコルでのみアクセスできます。http プロトコルはうまく機...

Mysqlツリー再帰クエリの実装方法

序文部門テーブルなどのデータベース内のツリー構造データの場合、部門のすべての従属部門または部門のすべ...

Reactドラッグフックを実装するための100行以上のコード

序文ソースコードは合計で 100 行強しかありません。これを読めば、react-dnd などの成熟し...