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

ブログ    

推薦する

Mac インストール mysqlclient プロセス分析

仮想環境で pip 経由でインストールしてみてください: pip で mysqlclient をイン...

MySQL でよく使用されるデータベースとテーブル シャーディング ソリューションの概要

目次1. データベースのボトルネック2. サブライブラリとサブテーブル2. 横長テーブル3. 垂直サ...

URL 書き換えモジュール 2.1 URL 書き換えモジュールのルール記述

目次前提条件テストページの設定書き換えルールの作成命名規則モードの定義アクションの定義設定ファイル内...

MySQL 5.7.17 zip パッケージ バージョンを Windows 10 にインストールするチュートリアル

mysql5.7.17のインストールチュートリアルを参考までに共有します。具体的な内容は次のとおりで...

MySQL テーブル分割後にスムーズにオンラインになる方法

目次テーブルの目的例えばテーブル分割戦略すでにオンラインになっている実行中のテーブルはどうすればよい...

Vue+canvas は、ウォーターフォール チャートを上から下までリアルタイムに更新する効果を実現します (QT と同様)

早速ですが、デモ画像をご紹介します。実装されている機能は、左側に凡例、右側にウォーターフォール チャ...

Docker ファイルの保存パス、ポート マッピング操作モードの変更

コンテナの起動コマンドを取得する方法コンテナはすでに作成されていますが、その起動パラメータ(データが...

Tomcat9 のダウンロード、インストール、設定 + Eclipse への統合に関する詳細なチュートリアル

トムキャット公式サイトtomcatはローカルサーバーと同等であり、Webページを開くことができます設...

Dockerはホスト間のネットワーク通信を実現するためにMacvlanを導入する

基本的な概念: Macvlanの動作原理: Macvlan は、Linux カーネルでサポートされて...

マルチポートおよびマルチドメイン名アクセスのNginx構成の実装

サーバーに複数のサイトを展開するには、異なるサイトにアクセスするために複数のポートを開く必要がありま...

JavaScript 関数構文の説明

目次1. 通常の機能2. 矢印関数3. データパケットJSON 4. オブジェクト5. 約束6. 非...

Windows 10 での MySQL 8.0.19 のインストールと設定のチュートリアル

来学期にMySQLを勉強します。事前に自宅で練習していませんでした。インストールに時間がかかるとは思...

Vue テンプレート構成と Webstorm コード形式仕様設定

目次1. コンパイラコードフォーマット仕様設定2. Vueテンプレートの設定1. コンパイラコードフ...

MySQLのネストされたトランザクションで発生する問題

MySQL はネストされたトランザクションをサポートしていますが、それを実行する人は多くありません....

GaussDB for MySQL パフォーマンス最適化の詳細な説明

目次背景インスピレーションは人生から生まれる速達配送の最適化原則GaussDB の最適化 (MySQ...