Vue の長いリストをすばやく読み込む方法

Vue の長いリストをすばやく読み込む方法

vue-long-list-load、特殊な条件を満たす長いリストの読み込み。サポート: 1. 各ノードの高さは異なり、自由に設定できます。 2. 各ノードは、読み込み効果に影響を与えずに変更できます。 3. 指定された位置まで正確にスクロールできます。

背景

長いリストをレンダリングする要件があり、当初は vue-virtual-scroll-list が使用されていました。しかし、各ノードの高さは異なるため、使用するには少し問題があります。対応するニーズがある場合は、私の解決策を参照してください。誰でもコミュニケーションを歓迎します!

vue-長いリストの読み込み

特別な条件を満たす長いリストが読み込まれます。 リスト内のノードの高さは異なり、各ノードを変更して指定された場所に配置できます。 www.npmjs.com/package/vue…

メインコンテンツ

  1. vue-long-list-load と vue-virtual-scroll-list の比較
  2. Vue-long-list-load 実装のアイデア
  3. 基本コード
  4. プラグインの使い方
  5. プラグインパラメータの説明

1. コンポーネントの比較

vue-long-list-load と vue-virtual-scroll-list の 2 つのプラグインには、それぞれ長所と短所があります。プラグインを選択するときは、アプリケーションのシナリオに最適なものを選択する必要があります。以下は 2 つのプラグインの基本機能の比較です。 vue-long-list-load の主な機能は、各ノードのサイズが均一でないシナリオに適していることです。一方、vue-virtual-scroll-list は、ノードが非常に均一で、リストの長さが w で測定されるリストに適しています。

コンポーネントvue-長いリストの読み込みvue-仮想スクロールリスト
npmアドレスwww.npmjs.com/package/vue… www.npmjs.com/package/vue…
コアまず、DOM スペースを空にし、コンポーネントを表示領域に表示します。現在の表示領域に表示されるコンポーネントマウントを計算します
水平サポートサポート
リスト内での一貫性が高いサポートサポート
リスト内の高さが一致しないサポートサポートが不十分
指定されたコンポーネントまでスクロールしますサポート高さが一定でない場合の計算は不正確
スクロールイベントサポートサポート
コンポーネントの高さ変更イベントサポートサポート
コンポーネントの非表示サポートサポートされていません

2. 実装のアイデア

主なアイデアは、\color{red}{virtual dom} 仮想 dom を通じて各ノードを占有し、表示可能なビューポートの変化に応じて表示されるノードを表示することです。表示可能なビューポートに影響を与える要因を監視します。ページ全体の幅と高さの変更、ノードの高さの変更、特定のノードへのページのスクロールはすべて、ビューポートの変更に影響を与える可能性があります。ビューポートが変更されると、表示可能なノードが計算され、ノード コンポーネントにマウントされます。ビューポートにないノードは破棄され、空の div が保持されます。下の図は実装アイデアのフローチャートです。

3. キーメソッドソースコード分析

メインエントリの HTML 構造は次のとおりです。\color{red}{v-for}v−for は長いリスト長のノードを表示し、:style を通じて \color{red}{minimum height} の最小高さを設定します。最小高さを設定する理由は、この高さの値が正確でない可能性があるためです。実際のコンポーネントがレンダリングされるときに、最も正確な高さが計算されます。高さを直接使用すると、ノード内のコンポーネントが完全に表示されない可能性があります。同時に、各ノードには一意の ID (scrollItem_ 一意の識別子) が設定され、データに基づいて DOM 情報を取得するときに使用されます。ノード コンポーネントは一意のクラス (長い項目の一意の識別子) を定義します。これは主に、実際のリスト コンポーネントをマウントし、コンポーネントの高さの変化を監視するために使用されます。 showList[index]は、ノードが表示されるかどうかを制御する一意の識別子です。

  <!--html コード-->
  <テンプレート>
    <div 
      :
      :style="{'min-height': (item.height>=0?item.height:height) + 'px'}"
      :key="アイテム[データキー]"
      :id="'scrollItem_' + アイテム[データキー]"
      v-for="(item,index) in dataList" 
      >
      <長い項目 
        v-if="showList[インデックス]"
        :dataKey="データキー" 
        :item="アイテム"
        :boxHeight="アイテムの高さ||0"
        :direction="方向"
        :heightChange="高さ変更"
        :extendCcomments="コメントを拡張"> 
      </long-item>
    </div>
  </テンプレート>

showList[index]がtrueの場合、対応するノードが表示されます。マウントされたライフサイクル中に、long-item は extendCcomments をコールバックします。 \color{red}{Vue.extend Profile}Vue.extendProfile を通じて対応する DOM にマウントします。 ComponentProps はノード コンポーネントから渡されるいくつかのパラメーターであり、マウント時にすべてマウントされます。

 <!--コンポーネントをマウント-->
  拡張コメント(アイテム){
    this.componentProps.item=アイテム
    var Profile = Vue.extend(this.dataComponent);
        // Profileインスタンスを作成し、要素にアタッチする new Profile({
          propsData: this.componentProps
        }
      ).$mount('.long-item-'+item[this.dataKey]);
  }

\color{red}{element-resize-detector}element−resize−detector は、DOM サイズの変更を監視するために使用されます。各ノードの幅と高さが変更され、元のサイズと異なる場合、heightChange メソッドがコールバックされ、サイズが更新され、表示ノードで演算計算が実行されます。

 <!--各ノードのサイズが変わります-->
  this.$nextTick(()=> {
    this.$DomListener.listenTo(document.getElementById('long-item-'+this.item[this.dataKey]), (要素)=>{
      if (this.boxHeight != element[this.directionConfig.width]) {
        this.heightChange(this.item, 要素[this.directionConfig.width])
      } 
    })
  });

表示可能なビューポート領域を取得するメソッドです。ページがスクロールしてサイズが変わるときに呼び出されるため、このメソッドが呼び出されたときには手ぶれ補正処理が行われます。300ms以内に連続して呼び出しがあった場合は最後の呼び出しのみ実行され、そうでない場合は頻繁な計算はパフォーマンスに影響します。表示可能なビューポート領域は、現在のビューポートとその前後の 2 つのビューポートの合計 3 つのビューポートのサイズとして計算されます。これにより、狭いスクロール範囲でより良いエクスペリエンスが得られます。

  getShowLimit(開始トップ) {
    const scrollTop = startTop || this.scrollWrap[this.directionConfig.scrollTo] || 0; // スクロール距離 this.viewClientHeight = this.scrollWrap[this.directionConfig.width]; // 表示領域の高さ this.scrollTop = scrollTop
    this.showStart = scrollTop - this.viewClientHeight
    this.showEnd = scrollTop + 2*this.viewClientHeight
    if(this.setTopTimer){
      タイムアウトをクリアします(this.setTopTimer)
    } 
    this.setTopTimer = setTimeout(() => {
      this.setItemTopheight() 関数
    }, 300);
  },

ノードが高さまたは幅に基づいて表示されるかどうかを計算します。この計算は比較的大きく、このメソッドは他のメソッドとは関係がないため、計算を実行するには別のスレッドを開きます。 \color{red}{simple-web-worker}simple−web−worker プラグインを導入すると、ノードを計算して表示するための別のスレッドが開かれます。主な計算方法は 3 つあります。現在のノードの開始が表示ビューポート内にある場合、現在のノードの終了が表示ビューポート内にある場合、現在のノードの開始も終了も表示ビューポート内にない場合です。 3 つのケースがあり、そのうちの 1 つが満たされている限り、ノードはビューポートに表示されます。

  // 高さに基づいてノードが表示されるかどうかを計算する setItemTopheight(){
    stsartId = this.dataList[0]&&this.dataList[0][this.dataKey]とします。
    startDom = stsartId && document.getElementById('scrollItem_'+stsartId) とします。
    startTop = startDom とします。startDom[this.directionConfig.offset] : 0
    this.worker = this.$worker.run((dataList,showStart,showEnd, startTop,hideIds,dataKey,height) => {
      let topHeight = startTop; // タイトルの上端から上端までの距離 let bottomHeight = 0; // タイトルの下端から上端までの距離 let showList = []
      for(let i=0,len=dataList.length;i<len;i++){
        アイテム = dataList[i]とする
        if(hideIds.indexOf(item[dataKey]) != -1){
          showList[i] = false;
          続く;
        }
        下の高さ = 上の高さ + (item.height>=0?item.height:height)
        // 判断 1. 質問の上部が表示範囲内にある 2. 質問の下部が表示範囲内にある 3. 質問の上部も下部も表示範囲内にない if((topHeight>=showStart && topHeight<=showEnd)||
          (bottomHeight>=表示開始 && bottomHeight<=表示終了)||
          (topHeight<showStart && bottomHeight>showEnd) ){
          showList[i] = true}
         それ以外{
          showList[i] = 偽
        } 
        topHeight += ((item.height>=0?item.height:height));
      }
      showList を返す
    }, [this.dataList、this.showStart、this.showEnd、startTop、this.hideIds、this.dataKey、this.height])
    .then(res => {
      this.showList = res
    })
    this.worker = null
  },

4. 使用方法

vue-long-list-load をインストールします。

npm をインストール vue-long-list-load --save

プロジェクト内での呼び出し

<長いリスト 
 ref="vueLongList"
 データキー='id' 
 スクロールラップ
 :dataList="データリスト" 
 :dataComponent="データコンポーネント" 
 :componentProps="コンポーネントプロパティ"
 高さ=100
 > 
</長いリスト>

5. パラメータの説明

パラメータ例示するタイプ必須オプション値デフォルト値
スクロールラップIDリストスクロールコンテナID真実
データキーノードデータ内の一意のキー値真実
データリストリストデータ配列真実詳細については以下の手順を参照してください
データコンポーネントカスタムノードコンポーネント真実
参照コンポーネントの内部メソッドの呼び出し間違い
方向スクロール方向番号間違い0: 垂直、1: 水平0
非表示IDリスト内の非表示にする必要があるノード配列間違い詳細については以下の手順を参照してください[]
身長ノードの高さ番号間違い 100
コンポーネントプロパティノードコンポーネントに渡されるパラメータ物体間違い {}
スクロールスクロール領域でのスクロールコールバックメソッド関数間違い-
サイズ変更ノードの幅と高さが変更されたときのコールバックメソッド関数間違い詳細については以下の手順を参照してください

いくつかのパラメータの説明

  &lt;--dataKey=id と仮定-->
  
  &lt;--リスト内で非表示にするノード-->
  非表示ID:[1, 2]
  &lt;--リストデータ dataList の高さは **Number** です。 -->
  データリスト:[
    {id:1,高さ:100},
    {id:2,高さ:200},
    {id:3,高さ:300},
    {id:4,高さ:300},
    {id:5,高さ:300}
  ]
  
  &lt;--ノードの高さ-->
  高さ:100
  &lt;--dataList に高さの値がある場合は、この高さを設定する必要はありません-->
  &lt;--dataList も height も渡されない場合は、デフォルト値は 100 となり、スクロールに若干の遅延が生じる可能性があります。 -->
  &lt;--それぞれの高さが異なる場合はdataListに渡し、同じ場合はheightに渡すことをお勧めします-->
  
  &lt;--ノードの幅と高さが変更されると、コールバック メソッドは ID と高さをパラメーターとして返します -->
  サイズ変更(id, 高さ){ }

要約する

プロジェクトの実際のデータによると、基本的に各ノードには少なくとも 500 個の DOM ノードがあり、平均は 800 個以上の DOM ノードがあります。vue-long-list-load を使用すると、レンダリング領域にないトピックに対して 2 つの DOM ノードのみがレンダリングされます。通常計算では、DOM ノードが約 800 個の場合、一般的なレンダリング領域にレンダリングされるノード数は約 9 個です。n 個のノードのリストであれば、DOM のロードと操作ごとに (n-9)x(800-2) 個の DOM ノードのレンダリングが削減されます。1000 個のノードのリストを毎回ロードして操作すると、726180 個の DOM ノードのレンダリングが削減されることに相当します。最初のレンダリングと修正された再描画により、DOM レンダリングが大幅に削減され、読み込み速度が高速化され、ユーザー エクスペリエンスが向上します。 このソリューションはしばらく前からプロジェクトに実装されており、ユーザーからのフィードバックは非常に良好です。同様のシーン要件がある場合は、ぜひご利用ください。通信します!

上記は、Vue の長いリストをすばやく読み込む方法の詳細です。Vue の長いリストを高速に読み込む方法の詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • Vueは無限ロードリスト機能を実装します
  • 詳細ページ操作のパラメータを含む Vue リスト ページ (router-link)
  • vue パブリック リスト選択コンポーネント、Vant-UI スタイルの参照
  • Vue はフロントエンドリストの複数条件フィルタリングを実装します
  • Vueは、「詳細を表示」ボタンをクリックして詳細リストをポップアップウィンドウに表示する操作を実装します。
  • vueのリスト画像の確認操作について
  • Vue-Extensionとリストの下の詳細の折りたたみケース
  • vue v-forから出てくるリストで、特定のliをクリックすると、現在クリックされているliのフォントが赤くなります。
  • Vueは円形スクロールリストを実装します
  • Vueはリストスクロールの遷移アニメーションを実装します

<<:  Docker-compose ワンクリックデプロイ gitlab 中国語版の方法手順

>>:  CentOS6.9+Mysql5.7.18 ソースコードのインストール詳細チュートリアル

推薦する

nginx-ingress-controller ログ永続化ソリューションのソリューション

最近、nginx-ingress-controller のアプリケーションについて説明した公開アカウ...

CentOS 7.4 に MySQL 5.7 を手動でインストールする方法

MySQL データベースは、特に JAVA プログラマーの間で広く使用されています。クラウド データ...

Mysql-connector-java ドライバのバージョン問題の概要

Mysql-connector-java ドライバのバージョンの問題私のデータベースのバージョンは ...

display または visibility を通じて HTML 要素を表示または非表示にする

場合によっては、特定の条件に基づいて Web ページ内の HTML 要素を表示するか非表示にするかを...

VMware で Centos7 ブリッジ ネットワークを構成する手順の詳細な説明

VMware仮想マシンでのCentos7ブリッジネットワーク構成の完全な手順は参考用です。具体的な内...

Windows の MySQL net start mysql MySQL サービスの起動エラーが発生する システムエラーの解決

目次1- エラーの詳細2-シングルソリューション2.1-ディレクトリ C:\Windows\Syst...

純粋な CSS で中空効果を実現するためのサンプルコード

私は最近、空洞化効果について研究しました。背景クリップ: テキスト背景はテキストの前景色にクリップさ...

MySQL MHA 操作ステータス監視の概要

目次1. プロジェクトの説明1.1 背景1.2 実装設計1.2.1 従来の方法1.2.2 最適化され...

モバイル アプリのユーザー インターフェース設計に関する 10 のヒント

ヒント1: 集中力を保つ最高のモバイル アプリは、1 つのことを非常にうまく行うことに重点を置いてい...

nginx で Vue プロジェクトをデプロイする方法

今日は nginx サーバーを使用するのですが、vue プロジェクトをサーバーにデプロイする必要もあ...

JavaScript を使用せずに HTML の a タグを無効にするには、純粋な CSS を使用します。

実際、この問題は、HTML の select タグを初めて学んだときにすでに発生していました。今日に...

Nginx転送マッチングルールの実装

1. 正規表現マッチング大文字と小文字を区別するマッチングの場合 ~ ~*は大文字と小文字を区別しな...

GNU Parallelの具体的な使用法

それは何ですか? GNU Parallel は、1 台以上のコンピュータでコンピューティング タスク...

nginx サーバーでの 502 不正なゲートウェイ エラーの原因のトラブルシューティング

パブリックアカウントのファンデータを同期してバッチプッシュするときに、サーバーがエラー502を報告し...