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) の解決方法

推薦する

WeChatミニプログラムQRコード生成ツール weapp-qrcode 詳細説明

WeChat ミニプログラム - QR コード ジェネレーターダウンロード: weapp-qrcod...

webpackでvue環境を構築する際の異常なエラーを解決する

目次まず、package.jsonを設定します次にwebpackツールをインストールしますwebpa...

Better-scrollはメニューとコンテンツをリンクする効果を実現します

1. 基本的な使い方 <!DOCTYPE html> <html lang=&qu...

SASSで変数のデフォルト値を使用する方法

SASS で定義された変数では、後で設定された値によって古い値が上書きされます。 $色: 赤; $色...

iptables および firewalld ツールを使用して Linux ファイアウォール接続ルールを管理する

ファイアウォールファイアウォールは一連のルールです。パケットが保護されたネットワーク空間に出入りする...

MySQLスローログに関する知識のまとめ

目次1. スローログの紹介2. スローログの練習1. スローログの紹介スロー ログの正式名称はスロー...

Linux 環境変数の設定方法のまとめ (.bash_profile と .bashrc の違い)

Linux では、アプリケーションをダウンロードしてインストールすると、起動時にアプリケーション名...

CSS3 は本当に SCSS に取って代わるのでしょうか?

Web ページのスタイル設定に関しては、プロジェクトで純粋な CSS または SCSS (および他...

HTMLはWEB標準の開発の中心的な基盤です

HTML 中心のフロントエンド開発は、ほぼ Web 標準の意味です。共通しているのは「分離」という考...

JavaScriptクロージャの原理と機能の詳細な説明

目次導入クロージャの使用カレー作りパブリック変数の実装キャッシュカプセル化(属性のプライベート化)閉...

Linuxコマンドに基づいてフォルダー内の特定のファイルパスを抽出します

最近では、特定のフォルダ内の特定のファイルを自動的に検索する必要があり、ファイルパスとファイル名を別...

VSCode の JS フォーマットでセミコロンを自動的に追加または削除する方法について

導入js コード文の末尾にセミコロンを追加しても追加しなくても問題ありません。一般的に、チームで開発...

Vueのコンポーネント値の転送から始まるオブザーバーモードの詳細な説明

目次オブザーバーパターンVue パス値最初のステップは、main.jsにバスを登録することです。 2...

Centos7でのMySQLインストールチュートリアル

MySQLインストールチュートリアル、参考までに具体的な内容は次のとおりです。 1. ダウンロードY...

MySQL の起動オプションとシステム変数の例の詳細な説明

目次ブートオプションコマンドラインパラメータの長い形式と短い形式設定ファイル構成グループシステム変数...