Vue Routerはバックグラウンドデータに応じて異なるコンポーネントをロードします

Vue Routerはバックグラウンドデータに応じて異なるコンポーネントをロードします

実際のプロジェクトで遭遇する要件

同じリンクで異なるページ コンポーネントを読み込む必要があります。ユーザーが購入したサービスに応じて異なるページが表示されます。

実装が間違っているところもある

  • これらのコンポーネントを同じコンポーネントの下に記述し、v-if を通じて判断するだけです。こうすれば、vue-router を使う必要すらありません。 1 つのファイルにすべてのコンポーネントを記述し、v-if を使用してすべてを判断できます。 (面倒でも構わないのであれば、コードが何万行もあることが前提です)
  • このリンクをレンダリングするときは、バックグラウンド データを直接要求し、そのデータに基づいて異なるリンクをレンダリングします。 (理論的には可能ですが、ユーザーがこの機能を使用しない場合、これらのリンクは毎回バックグラウンドデータを事前に取得します。また、ユーザーがリンクを知っていて直接リンクにアクセスする場合、ユーザーがどのページを見るべきかを判断するロジックが依然として必要です)
  • router.beforeEach を呼び出すことで、各ルートがインターセプトされます。ルートが指定したルートである場合、バックグラウンド データが要求され、ページが動的にジャンプします。 (機能は完成しますが、実際にはこれはシステム全体のごく一部に過ぎず、ルーティングシステム全体を侵害するものではありません。各業務ページをグローバルルーティングシステムに書き込むと、ルーティングロジックが複雑になりすぎてしまいます。)

私は個人的に、実装するより良い方法は

ルートが設定されているサーバーデータを取得し、対応するコンポーネントを動的にロードします。

{
  パス: 'shopKPI',
  // バックグラウンドデータを事前にストアに保存しておけば、ここでストアデータにアクセスして直接判断できます // ただし、この特定のビジネスページのデータはグローバルストアに配置され、他の場所では使用されないため、実際には不要なコンポーネントです: () => import('@/views/store/dataVersion'),
  名前: 'store_KPI',
  メニュー名: 'ショップコンサルタント',
  メタ: {
    コード: ['storeProduct.detail']
  }
}

理想は素晴らしいですが、現実には、コンポーネントが受信したメソッドは同期的に Promise を返す必要があります。

この時、上記の悪い実装方法1を思い出し、少し修正しました。

<!-- ChooseShopKPI.vue -->
<テンプレート>
  <dataVersion v-if="!useNewShopKPI" />
  <ShopKPI v-else />
</テンプレート>

<スクリプト>
'lodash' から { get } をインポートします。
'@/api/store' から { getStoreReportFormVersion } をインポートします。
'./dataVersion' から dataVersion をインポートします。
'./ShopKPI' から ShopKPI をインポートします。

エクスポートデフォルト{
  名前: 'ChooseShopKPI',

  コンポーネント:
    データバージョン、
    ショップKPI、
  },

  データ() {
    戻り値: {useNewShopKPI: false };
  },

  作成された() {
    getStoreReportFormVersion().then((res) => {
      (res、'data.data.new')を取得する場合){
        this.useNewShopKPI = true;
      }
    });
  },
};
</スクリプト>

<style lang="css" スコープ></style>

ルートレンダリングに対応するページを変更して、この中間ページ ChooseShopKPI をレンダリングします

{
  パス: 'shopKPI',
  // 事前に背景データを取得しておけば、ここでストアデータにアクセスして直接判断できます // ただし、この特定のビジネスページのデータはグローバルストアに配置され、他の場所では使用されないため、実際には不要です - コンポーネント: () => import('@/views/store/dataVersion'),
+ コンポーネント: () => import('@/views/store/ChooseShopKPI'),
  名前: 'store_KPI',
  メニュー名: 'ショップアドバイザー',
  メタ: {
    コード: ['storeProduct.detail']
  }
}

これにより、期待どおりの機能が実現されます。

機能は実現したが、改めて考えてみた

この方法は、ページ コンポーネントを動的に読み込むという問題を非常にうまく解決します。しかし、いくつかの小さな問題も発生しました。

  • 後でサーバー経由でデータを読み込むページが追加されると、複数の ChooseXXX 中間ページが表示されます。
  • この種の中間ページは、実際には二次ルーティングを実行します。ロジックに精通していない開発者は、ここでのページ ジャンプ ロジックを明確に理解できない可能性があり、理解コストが増加します。

最終ソリューション - 高レベルコンポーネント

ChooseXXXを抽象化してDynamicLoadComponentに変換する

<!-- DynamicLoadComponent.vue -->
<テンプレート>
  <コンポーネント:is="comp" />
</テンプレート>

<スクリプト>
エクスポートデフォルト{
  名前: 'DynamicLoadComponent',
  小道具: {
    レンダリングコンポーネント: {
      タイプ: 約束、
    },
  },
  データ() {
    戻る {
      comp: () => this.renderComponent
    }
  },
  マウント() {},
};
</スクリプト>

<style lang="css" スコープ></style>

ルーティング構成でバックグラウンドデータを直接取得し、ルートを配布します。このように、ルーティング ロジックはルーティング構成ファイルに集中しており、セカンダリ ルーティングは存在しません。メンテナンスは面倒ではありません。

DynamicLoadComponent コンポーネントも再利用でき、バックグラウンド データの読み込みページを決定するための後続のルーティング構成をこの中間コンポーネントに送信できます。

{
  パス: 'shopKPI',
  コンポーネント: () => import('@/views/store/components/DynamicLoadComponent'),
  名前: 'store_KPI',
  メニュー名: 'ショップコンサルタント',
  メタ: {
    コード: ['storeProduct:detail'],
  },
  プロパティ: (ルート) => ({
    レンダリングコンポーネント: 新しい Promise((resolve, deny) => {
      getStoreReportFormVersion()
        .then((レスポンスデータ) => {
          レスポンスデータに新しいショップKPI を追加します。
          定数useOldShopKPI = get(
            レスポンスデータ、
            'データ.データ.ストア_データ_表示'
          );

          (新しいショップKPIを使用する場合) {
            解決します(インポート('@/views/store/ShopKPI'));
          } そうでない場合 (OldShopKPI を使用) {
            解決します(インポート('@/views/store/dataVersion'));
          } それ以外 {
            解決します(インポート('@/views/store/ShopKPI/NoKPIService'));
          }
        })
        .catch(拒否);
    })、
  })
}

オンラインサンプルを表示(Chrome のみサポート)
https://stackblitz.com/edit/vuejs-starter-jsefwq?file=index.js

これで、Vue Router がバックグラウンド データに応じて異なるコンポーネントをロードする方法についての説明は終わりです。Vue Router がバックグラウンド データに応じて異なるコンポーネントをロードする方法についての詳細は、123WORDPRESS.COM の以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • vue-router データの読み込みとキャッシュの使用状況の概要の詳細な説明

<<:  MySQL 5.7 でパスワードを変更するときに発生する ERROR 1054 (42S22) の解決方法

>>:  MySQL サーバー ログイン エラー ERROR 1820 (HY000) の解決方法

推薦する

シンプルなスネークゲームを実現するネイティブjs

この記事では、スネークゲームを実装するためのjsの具体的なコードを参考までに共有します。具体的な内容...

レスポンシブ原則のソースコード分析のVue解釈

目次初期化初期化状態()初期化プロパティ()初期化データ()観察する()オブザーバーリアクティブを定...

MYSQL 文字関数を使用してデータをフィルタリングすることに関する質問

問題の説明:構造:テストには2つのフィールドがあります。これらは col1 と col2 で、どちら...

Nginx で limit_req_zone を使用して同じ IP へのアクセスを制限する方法

Nginx は、ngx_http_limit_req_module モジュールの limit_req...

Linux でシェル スクリプトを使用して jar パッケージ プロジェクトを展開するための完全な手順

1. JDKをインストールする コンピュータの動作桁を確認します。 uname -ar 2017 x...

ミニプログラムカスタムタブバーコンポーネントのカプセル化

この記事の例では、ミニプログラムのカスタムタブバーコンポーネントをカプセル化するための具体的なコード...

MySQLコマンドが中国語で入力できない問題の解決方法

問題を見つける最近、MySQL コマンドを使用して MySQL サーバーに接続したときに、以下のよう...

フレックスレイアウトでコンテナ内のコンテンツを維持するためのソリューションの詳細な説明

モバイル側では、フレックスレイアウトが非常に便利です。デバイスの幅に応じてコンテナの幅を自動的に調整...

Nginx ロードバランシングの設定方法

目次Nginx 負荷分散構成Nginx 負荷分散戦略ポーリング(デフォルト)重さip_ハッシュ公正(...

JS はシンプルなカレンダー効果を実装します

この記事では、シンプルなカレンダー効果を実現するためのJSの具体的なコードを参考までに紹介します。具...

Linuxで大きなファイルを素早くコピーする方法

データをコピーリモートでデータをコピーする場合、通常は rsync コマンドを使用しますが、小さなフ...

Vue で pdfjs を使用して PDF ファイルをプレビューする方法

目次序文考えるライブラリディレクトリの解析とダウンロード使い方ファイルの場所実際の通話質問要約する序...

Linux ディスクのマウント、パーティション分割、容量拡張操作を実装する方法

基本概念操作の前に、まずいくつかの基本的な概念を理解する必要がありますディスクLinux システムで...

JavaScript コードを省略する一般的な方法の概要

目次序文矢印関数一般的な配列操作をマスターするスプレッド演算子オブジェクトの省略形構造化割り当てデー...

Ubuntuはポート22を開きます

シナリオssh 経由で Ubuntu サーバーに接続するには、xshell ツールを使用する必要があ...