Vue/React シングルページ アプリケーションをリフレッシュなしで復元するソリューション

Vue/React シングルページ アプリケーションをリフレッシュなしで復元するソリューション

導入

進むときに更新し、戻るときに更新しないという機能は、アプリ ページの機能に似ています。ただし、シングル ページ Web アプリケーションでこれを実現するのは簡単ではありません。

なぜわざわざ?

spa のレンダリング原則 (vue を例に挙げます) : URL の変更により onHashChange/pushState/popState/replaceState がトリガーされ、URL 内の pathName を使用してルートで定義されたコンポーネントが照合され、読み込まれ、インスタンス化されて、プロジェクトのエクスポート ルーター ビューでレンダリングされます。

つまり、レンダリングの出口は 1 つしかないため、1 つのインスタンスを解析してレンダリングすると、別のインスタンスが破棄されることになります。

キープアライブが機能しないのはなぜですか?キープアライブの原則はインスタンス化されたコンポーネントを保存することであるため、次回 URL が変更されたコンポーネントと一致すると、まずストレージから取得されます。

ただし、Vue はストレージを入力する方法のみを提供し、ストレージを削除する方法は提供していないため、「フォワードリフレッシュ」を実装することはできません。

1 つの解決策は、to と from に基づいて前方と後方の判断を手動で行うことです。この判断では、複雑なジャンプ ロジックに対応できず、保守性も低くなります。

落とし穴のあるコミュニティソリューション(Vue を例に挙げる)

vue-page-stackvue-navigation
どちらのソリューションにも明らかな欠点があります。前者はネストされたルーティングをサポートしておらず、シナリオによっては URL が変更され、ページが完全に応答しなくなる可能性があります。後者にも同様のバグがあります。どちらのソリューションも、vue-router の魔法の変更に基づいているため、非常に侵襲的です。そして、URLに意味のない追加フィールド(stackID)が追加されます

現時点では良い計画だ

現在、実行可能でシンプルなソリューションがあります。ネストされたサブルート + スタックされたページです。
ページをスタックするきっかけ: ネイティブ アプリケーションでは Webview 内に Webview、マルチページ アプリケーションではウィンドウ内にウィンドウ。
SPA でリフレッシュなしのバックアップを実現するには、複数のインスタンスの共存を実現することが不可欠です。
このソリューションの中核は、ネストされたサブルートを通じて複数インスタンスの共存を実現し、CSS 絶対を通じて視覚的なページ スタッキングを実現することです。

効果画像

Vueでの実装

ルート構成ファイル内:

「../views/Home.vue」から Home をインポートします。

定数ルート = [
  {
    パス: "/home",
    名前: "ホーム",
    コンポーネント: ホーム、
    子供たち: [
      {
        パス: "sub",
        コンポーネント: () =>
          import(/* webpackChunkName: "sub" */ "../views/Sub.vue"),
      },
    ]、
  },
];

デフォルトルートをエクスポートします。

ホームページ:

<テンプレート>
  <div class="home">
    <input v-model="入力値" />
    <h3>{{ 入力値 }}</h3>
    <button @click="handleToSub">サブスクライブする</button>
    <ルータービュー @reload="handleReload" />
  </div>
</テンプレート>

<スクリプト>
エクスポートデフォルト{
  名前: "ホーム",
  データ() {
    戻る {
      入力値: "",
    };
  },
  メソッド: {
    ハンドルToSub() {
      // ルーティング形式は、独立した /sub ではなく、前のルート /home の下のサブに基づいていることに注意してください。
      this.$router.push("/home/sub");
    },

    ハンドルリロード(val) {
      // ここでは、詳細ページでデータを変更したり、console.log("reload", val); を返した後にリストを再度取得するなど、データを再取得するための操作をいくつか実行できます。
    },
  },
  マウント() {
    // サブページが戻り、ライフサイクルは再実行されません console.log("mounted");
  },
};
</スクリプト>

<スタイルスコープ>
。家 {
  位置: 相対的;
}
</スタイル>

サブページ:

<テンプレート>
  <div class="sub">
    <h1>これはサブページです</h1>
  </div>
</テンプレート>

<スクリプト>
エクスポートデフォルト{
  破棄する前に() {
    // カスタムパラメータを渡すことができます。必要ない場合は、これを行う必要はありません。$emit("reload", 123);
  },
};
</スクリプト>

<スタイルスコープ>
.sub {
  位置: 絶対;
  左: 0;
  上: 0;
  幅: 100%;
  高さ: 100%;
  背景色: #fff;
}
</スタイル>

Reactでの実装

ルート:

「react-router-dom」から Route をインポートします。

const ルート = () => {
  戻る (
    <>
      ** 最初に親ページを一致させてから子ページを一致させる必要があるため、ここでは正確な値を追加できません*/
      <ルート パス="/home" コンポーネント={lazy(() => import("../views/Home"))} />
    </>
  );
};

デフォルトのルートをエクスポートします。

ホームページ:

「react」から React をインポートし、{useEffect、useState} を追加します。
「react-router-dom」から Route、useHistory をインポートします。
「styled-components」からstyledをインポートします。
「./Sub」からSubをインポートします。

const HomeContainer = styled.div`
  位置: 相対的;


const ホーム: React.FC = () => {
  const [入力値、設定入力値] = useState("");
  定数履歴 = useHistory();

  定数handleToSub = () => {
    history.push("/home/sub");
  };

  const handleReload = (val: 数値) => {
    console.log("リロード", val);
  };

  使用効果(() => {
    console.log("マウントされました");
  }, []);

  戻る (
    <ホームコンテナ>
      <入力
        値={入力値}
        onChange={(e) => setInputValue(e.target.value)}
      />
      <h3>{入力値}</h3>
      <button onClick={handleToSub}>サブスクライブする</button>
      <ルート
        パス="/home/sub"
        コンポーネント={() => <Sub handleReload={handleReload} />}}
      />
    </ホームコンテナ>
  );
};

デフォルトのホームをエクスポートします。

サブページ:

「react」からReactをインポートします。
「styled-components」からstyledをインポートします。

const サブコンテナ = styled.div`
  位置: 絶対;
  左: 0;
  上: 0;
  幅: 100%;
  高さ: 100%;
  背景色: #fff;


タイプ サブプロパティ = {
  handleReload: (val: number) => void;
};

const Sub: React.FC<SubProps> = ({ handleReload }) => {
  使用効果(() => {
   戻り値 () => handleReload(123);
  }, []);
  
  戻る (
    <サブコンテナ>
      <h1>これはサブページです</h1>
    </サブコンテナ>
  );
};

デフォルトのサブをエクスポートします。

話題外

以前勤めていた会社の中核プロジェクト「Ping An Good Car Owner」では、いくつかの新しい h5 プロジェクトでこのソリューションを使用しましたが、オンラインで 170 万回を超える訪問のテストにも耐えました。この h5 ソリューションは現在 Shopee で宣伝されています。そのシンプルなロジックにより、多くの同僚に認知され、使用されています。たとえば、よくある例としては、リストページに検索条件があり、詳細ページを入力してから戻る、といったものがあります。 ぜひ試してみてください。きっと驚かれると思います。

このプログラムの利点

  • シンプルな実装、非侵入的な変更、ほぼゼロのロジック。
  • サードパーティのアクセス用にサブページを別途提供できます。
  • 複数のインスタンスが完全に共存し、戻ったときに更新されません。
  • 親子コンポーネントのように通信し、子ページの退出を監視できます。

欠点

ルーティング形式を変更し、ネストする必要があり、URL には特定の要件があります。
githubアドレス
https://github.com/zhangnan24/no-refresh-back-vue

これで、vue/react シングルページ アプリケーションの back-not-refresh の解決策に関するこの記事は終了です。vue/react の back-not-refresh に関する関連コンテンツの詳細については、123WORDPRESS.COM で以前の記事を検索するか、以下の関連記事を引き続き参照してください。今後も 123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • キープアライブ使用時にVueシングルページが更新されない問題を解決
  • vue2.0 でページをリフレッシュせずに前方にリフレッシュして戻る方法を実装する方法
  • Vue で動的に追加されたルーティング ページの更新時に失敗する理由と解決策
  • Vue が前のページに戻っても更新されない問題とその解決方法

<<:  MySQLテーブル構造を変更するコマンドを表示する

>>:  Spring Boot + jar パッケージングのデプロイメント Tomcat 404 エラーの問題を解決する

推薦する

VUEウォッチリスナーの基本的な使い方の詳しい説明

目次1. 次のコードはwatchの簡単な使用法です2. 即時監視3. ハンドラメソッド4. 深い属性...

MySQL サービスに iptables ファイアウォール ポリシーを追加するためのソリューション

MySQL データベースが Centos7 システムにインストールされており、オペレーティング シス...

nginx サーバーでの 502 不正なゲートウェイ エラーの原因のトラブルシューティング

パブリックアカウントのファンデータを同期してバッチプッシュするときに、サーバーがエラー502を報告し...

Mac+IDEA+Tomcat の設定手順

目次1. ダウンロード2. インストールと解凍3. Tomcatを起動する4番目に、インストールが成...

Vue.js スタイルレイアウト Flutter ビジネス開発共通スキル

シャドウスタイルにおけるフラッターとCSSの対応UIによって指定されたCSSスタイル 幅: 75px...

ダイナミッククロックを実現するJS+CSS

この記事の例では、動的な時計を実装するためのJS + CSSの具体的なコードを参考までに共有していま...

Nginx コンテンツ キャッシュと共通パラメータ設定の詳細

使用シナリオ:プロジェクトのページでは、頻繁に変更されず、個別のカスタマイズも伴わない大量のデータを...

sed コマンドを使用して文字列を置換する Linux チュートリアル

文字列を置き換えるには、次の形式を使用する必要があります。 $ sed s/置換対象文字列/置換文字...

Nginx ロケーション設定のチュートリアル (ゼロから)

基礎位置の一致順序は、「最初に正規表現に一致し、次に共通表現に一致」です。実際のロケーションの一致順...

And キーワードを使用した MySQL の複数条件クエリ ステートメント

AND キーワードを使用した MySQL 複数条件クエリ。MySQL では、AND キーワードを使用...

MySQL の自己結合重複排除に関する注意事項

機能シナリオを簡単に説明しましょう。データ行フィールドは次のとおりです。名前開始日時タイプこの表では...

nginxでの共有メモリの使用に関する詳細な説明

nginx プロセス モデルでは、トラフィック統計、トラフィック制御、データ共有などのタスクを完了す...

Linux でローカル コンピューターとリモート サーバーのポートが接続されているかどうかを確認する方法

以下のように表示されます。 1. ssh -v -p [ポート番号] [ユーザー名]@[IPアドレス...

CSSレイアウトにおけるフローティング問題に対する4つの解決策の詳細な説明

1. 原因:サブボックスをフロートに設定した後の効果: 青いボックスをフロートに設定すると、標準のド...

MySQLにおける静的変数の役割の詳細な説明

MySQLにおける静的変数の役割の詳細な説明静的変数の使用 静的変数サンプルコード: 関数テスト()...