背景長いリストをレンダリングする要件があり、当初は vue-virtual-scroll-list が使用されていました。しかし、各ノードの高さは異なるため、使用するには少し問題があります。対応するニーズがある場合は、私の解決策を参照してください。誰でもコミュニケーションを歓迎します! vue-長いリストの読み込み 特別な条件を満たす長いリストが読み込まれます。 リスト内のノードの高さは異なり、各ノードを変更して指定された場所に配置できます。 www.npmjs.com/package/vue… メインコンテンツ
1. コンポーネントの比較vue-long-list-load と vue-virtual-scroll-list の 2 つのプラグインには、それぞれ長所と短所があります。プラグインを選択するときは、アプリケーションのシナリオに最適なものを選択する必要があります。以下は 2 つのプラグインの基本機能の比較です。 vue-long-list-load の主な機能は、各ノードのサイズが均一でないシナリオに適していることです。一方、vue-virtual-scroll-list は、ノードが非常に均一で、リストの長さが w で測定されるリストに適しています。
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. パラメータの説明
いくつかのパラメータの説明 <--dataKey=id と仮定--> <--リスト内で非表示にするノード--> 非表示ID:[1, 2] <--リストデータ dataList の高さは **Number** です。 --> データリスト:[ {id:1,高さ:100}, {id:2,高さ:200}, {id:3,高さ:300}, {id:4,高さ:300}, {id:5,高さ:300} ] <--ノードの高さ--> 高さ:100 <--dataList に高さの値がある場合は、この高さを設定する必要はありません--> <--dataList も height も渡されない場合は、デフォルト値は 100 となり、スクロールに若干の遅延が生じる可能性があります。 --> <--それぞれの高さが異なる場合はdataListに渡し、同じ場合はheightに渡すことをお勧めします--> <--ノードの幅と高さが変更されると、コールバック メソッドは 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 の他の関連記事に注目してください。 以下もご興味があるかもしれません:
|
<<: Docker-compose ワンクリックデプロイ gitlab 中国語版の方法手順
>>: CentOS6.9+Mysql5.7.18 ソースコードのインストール詳細チュートリアル
最近、nginx-ingress-controller のアプリケーションについて説明した公開アカウ...
MySQL データベースは、特に JAVA プログラマーの間で広く使用されています。クラウド データ...
Mysql-connector-java ドライバのバージョンの問題私のデータベースのバージョンは ...
場合によっては、特定の条件に基づいて Web ページ内の HTML 要素を表示するか非表示にするかを...
VMware仮想マシンでのCentos7ブリッジネットワーク構成の完全な手順は参考用です。具体的な内...
目次1- エラーの詳細2-シングルソリューション2.1-ディレクトリ C:\Windows\Syst...
私は最近、空洞化効果について研究しました。背景クリップ: テキスト背景はテキストの前景色にクリップさ...
目次1. プロジェクトの説明1.1 背景1.2 実装設計1.2.1 従来の方法1.2.2 最適化され...
ヒント1: 集中力を保つ最高のモバイル アプリは、1 つのことを非常にうまく行うことに重点を置いてい...
今日は nginx サーバーを使用するのですが、vue プロジェクトをサーバーにデプロイする必要もあ...
HTML5 で contentEditable 属性が導入されて以来、div は textarea ...
実際、この問題は、HTML の select タグを初めて学んだときにすでに発生していました。今日に...
1. 正規表現マッチング大文字と小文字を区別するマッチングの場合 ~ ~*は大文字と小文字を区別しな...
それは何ですか? GNU Parallel は、1 台以上のコンピュータでコンピューティング タスク...
パブリックアカウントのファンデータを同期してバッチプッシュするときに、サーバーがエラー502を報告し...