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

推薦する

クールなバーコードエフェクトの作り方を教えます

声明:この記事では、Web ページ制作技術を使用して問題を包括的に解決するという考え方を反映して、W...

HTML はモバイル上で固定フローティング半透明検索ボックスを実装します

質問。モバイルショッピングモールシステムでは、ページの上部に検索ボックスがよく見られます。ブロガーは...

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

関連記事:初心者が学ぶ HTML タグ (3)導入された HTML タグは、必ずしも XHTML 仕...

React スキャフォールディングの構築方法を学ぶ

1. フロントエンドエンジニアリングの複雑さいくつかの小さなデモ プログラムを開発するだけであれば、...

Linux ホスト上で複数の MySQL データベースを起動する方法

今日は、Linux ホスト上で 4 つの MySQL データベースを起動する方法について説明します。...

Centos7 に mysql 8.0.13 (rpm) をインストールする詳細なチュートリアル

yum か rpm か? yum によるインストール方法は非常に便利ですが、公式サイトから MySQ...

幅と高さが可変の要素を中央に配置するための CSS ソリューション

1. 水平中央公開コード: html: <div class="parent&quo...

Docker に nginx をインストールし、https 経由でアクセスを構成する方法

1. 最新のnginx dockerイメージをダウンロードする $ docker pull ngin...

MySQL データベースのデータ テーブルの最適化、外部キーの分析、3 つのパラダイムの使用

この記事では、例を使用して、MySQL データベースのデータ テーブルの最適化、外部キーの使用、およ...

Flinkのフォールトトレラントメカニズムに関する簡単な説明:ジョブ実行とデーモン

目次1. ジョブ実行のフォールトトレランス1.1 タスクフェイルオーバー戦略1.2 ジョブ再開戦略2...

CSS で平均レイアウトを実現するためにネガティブ マージン テクノロジーを使用する方法

通常、IE ブラウザでの CSS の互換性の問題を解決するために、フロート レイアウトが使用されます...

OracleデータをMySQLデータベースに抽出する実装プロセス

Oracle データベースから MySQL データベースへの移行では、Oracle データベース モ...

CSSオーバーフローメカニズムについての簡単な説明

CSS オーバーフローのメカニズムを詳細に学ぶ必要があるのはなぜですか?実際の開発プロセスでは、コン...

CSS で画像アダプティブ コンテナを実装するいくつかの方法 (要約)

多くの場合、画像をコンテナのサイズに合わせて調整する必要があります。 1. imgタグ方式幅と高さを...

MYSQL row_number() および over() 関数の詳細な使用方法

構文フォーマット: row_number() over(partition by grouping ...