ホームページ  >  記事  >  ウェブフロントエンド  >  vuejsのルーティング実装原理を詳しく解説

vuejsのルーティング実装原理を詳しく解説

不言
不言転載
2018-10-24 10:28:322689ブラウズ

この記事では、vuejs のルーティング実装原理について詳しく説明します。必要な方は参考にしていただければ幸いです。

一般的なソース コードでは、window.history と location.hash が使用されます。

history の実装

window.history オブジェクトには、ブラウザとウィンドウの履歴が含まれます。書き込み時に履歴オブジェクトが使用されます。ウィンドウ接頭辞を使用する必要はありません。 History は、SPA フロントエンド ルーティングを実装するための主流の方法です。これには、いくつかの独自のメソッドがあります。

history.back()

ブラウザの [戻る] ボタンをクリックするのと同じです#。

##history.forward()ブラウザで進むボタンをクリックするのと同じ


history.go(n)

パラメータとして整数を受け入れ、その整数で指定されたページに移動します。たとえば、go(1) は forward() と同等、go(-1) は back() と同等、go(0) は同等です。現在のページを更新します。

If 移動された位置がアクセス履歴の境界を超えている場合、上記の 3 つのメソッドはエラーを報告しませんが、通知せずに失敗します。

HTML5 では、履歴オブジェクトは PushState() を提案します。これら 2 つのメソッドは、URL が変更されたかのように履歴スタックにデータを追加するために使用できます (以前は URL のみが変更され、履歴スタックが変更されました)。現在のフロントエンド ルーティングもこの原理に基づいています。

history.pushState

pushState(stateObj, title, url) メソッドは、データを履歴スタックに書き込みます。2 番目のパラメーターは、書き込まれるデータ オブジェクトです (640kB 以下)。パラメータはページのタイトル、3 番目のパラメータは URL (相対パス) です。

stateObj: 指定された URL に関連する状態オブジェクト。popstate イベントがトリガーされると、オブジェクトはコールバック関数に渡されます。このオブジェクトが不要な場合は、この * に null を入力できます。

title: 新しいページのタイトルですが、現在すべてのブラウザはこの値を無視するため、ここに null を入力できます。
url: 新しい URL は、現在のページと同じドメイン内にある必要があります。ブラウザのアドレス バーにこの URL が表示されます。
PushState に関しては、注目すべき点がいくつかあります。

pushState メソッドはページの更新をトリガーしませんが、履歴オブジェクトを変更し、アドレス バーは次のようなイベントが発生した場合にのみ反応します。前方と後方がトリガーされます (back() と forward() など)

ここの URL は、悪意のあるスクリプトが他の Web サイトの URL を模倣してユーザーを欺くことを防ぐために、同一生成元ポリシーによって制限されています。ポリシーに違反すると、エラーが報告されます。

history.replaceState

replaceState(stateObj, title, url) と PushState の違いは、現在のレコードを書き込むのではなく、置き換えて変更することです。閲覧履歴の残りはpushStateとまったく同じです。

popstate イベント

定義: 同じドキュメント (つまり、履歴オブジェクト) の閲覧履歴が変更されるたびに、popstate イベントがトリガーされます。

注: このイベントは、pushState メソッドまたは replaceState メソッドを呼び出すだけではトリガーされません。ユーザーがブラウザーの「戻る」ボタンおよび「進む」ボタンをクリックした場合、または JavaScript を使用して「戻る」、「進む」、および「進む」メソッドを呼び出した場合にのみトリガーされます。また、このイベントは同じドキュメントのみを対象とします。閲覧履歴の切り替えにより異なるドキュメントが読み込まれる場合、このイベントはトリガーされません。
使用法: 使用する場合、popstate イベントのコールバック関数を指定できます。このコールバック関数のパラメータはイベント オブジェクトであり、その state 属性は、現在の URL の PushState メソッドと replaceState メソッドによって提供される state オブジェクト (つまり、これら 2 つのメソッドの最初のパラメータ) を指します。

HISTORY は SPA フロントエンド ルーティング コードを実装します
<a class="spa">abc.html</a>
<a class="spa">123.html</a>
<a href="/rdhub" class="spa ">rdhub</a>
  // 注册路由
  document.querySelectorAll('.spa').forEach(item => {
    item.addEventListener('click', e => {
      e.preventDefault();
      let link = item.textContent;
      if (!!(window.history && history.pushState)) {
        // 支持History API
        window.history.pushState({name: 'history'}, link, link);
      } else {
        // 不支持,可使用一些Polyfill库来实现
      }
    }, false)
  });

  // 监听路由
  window.addEventListener('popstate', e => {
    console.log({
      location: location.href,
      state: e.state
    })
  }, false)
popstate监听函数里打印的e.state便是history.pushState()里传入的第一个参数,在这里即为{name: 'history'}

hash

ハッシュの基本的な概要

URL にはハッシュ http:/ を含めることができます/localhost :9000/#/rdhub.html

ウィンドウ オブジェクトに onhashchange というイベントがあります。このイベントは次の状況でトリガーされます:

  1. ブラウザのアドレスを変更します。最後に直接 #hash を追加または変更します;

  2. location.href または location.hash の値を変更することによって;

  3. トリガーすることによってアンカーされたリンクをクリックする ;

  4. 2 つの Web ページ アドレスのハッシュ値が異なる場合、ブラウザを前後に移動するとハッシュが変化する可能性があります。

ハッシュは SPA フロントエンド ルーティング コードを実装します

<a href="/rdhub" class="spa">rdhub</a>
<a href="/abc" class="spa">abc</a>
<a href="/123" class="spa">123</a>
<a href="/hash" class="spa">hash</a>
  document.querySelectorAll('.spa').forEach(item => {
    item.addEventListener('click', e => {
      e.preventDefault();
      let link = item.textContent;
      location.hash = link;
    }, false)
  });
  // 监听路由
  window.addEventListener('hashchange', e => {
    console.log({
      location: location.href,
      hash: location.hash
    })
  }, false)

ハッシュ モードと履歴モード。これら 2 つのモードはブラウザ インターフェイスを通じて実装されますが、次の点が異なります。 vue-router は、非ブラウザ環境用の抽象モードも用意しています。その原理は、配列スタックを使用してブラウザ履歴スタックの機能をシミュレートすることです。もちろん、上記は一部のコア ロジックにすぎません。システムの堅牢性を確保するために、ソース コードには多くの補助ロジックが含まれており、これも学ぶ価値があります。

2 つのモードの比較

pushState によって設定される新しい URL は、現在の URL と同じオリジンを持つ任意の URL にすることができますが、ハッシュは #, 以降の部分のみを変更できます。したがって、同じドキュメントの現在の URL でのみ設定できます。

pushState によって設定される新しい URL は、現在の URL とまったく同じにすることができます。これにより、レコードと新しい値も追加されます。スタックへのレコードの追加をトリガーするには、ハッシュによって設定される値が元のものと異なる必要があります。 Medium

pushState は stateObject を通じて任意のタイプのデータをレコードに追加できますが、ハッシュは短い文字列のみを追加できます。

pushState は、後で使用するために title 属性を追加で設定できます

履歴モードに関する問題

単一ページ アプリケーションの場合、理想的な使用シナリオは、アプリケーションに入るときにのみindex.htmlをロードすることであり、その後のネットワーク操作は Ajax を通じて完了し、ロードされることはありません。 URL はページを再リクエストしますが、ユーザーがアドレス バーに直接入力して Enter キーを押す、ブラウザが再起動してアプリケーションをリロードするなど、特殊な状況が発生することは避けられません。

ハッシュ モードでは、ハッシュ部分の内容のみが変更され、ハッシュ部分は HTTP リクエストには含まれません:

http://rdhub.cn/#/user/id / / など 再リクエストでは http://rdhub.cn/
のみが送信されるため、ハッシュ モードの URL に基づいてページをリクエストする場合は問題ありません。

履歴モードでは、通常のリクエスト バックエンド URL と同じになるように URL が変更されます
http://rdhub.cn/user/id
この場合、リクエストをバックエンドに再送信します。 , バックエンドに /user/id に対応するルーティング処理が設定されていない場合、404 エラーが返されます。

公式に推奨される解決策は、すべての状況をカバーする候補リソースをサーバーに追加することです。URL が静的リソースに一致しない場合は、アプリが依存する同じindex.html ページが返されるはずです。ページ上で。同時に、これを実行すると、すべてのパスに対して Index.html ファイルが返されるため、サーバーは 404 エラー ページを返さなくなります。これを回避するには、Vue アプリケーションですべてのルーティング状況をカバーしてから、404 ページを与えます。または、Node.js をバックエンドとして使用する場合は、サーバー側のルーティングを使用して URL を照合し、一致するルートがない場合に 404 を返すことにより、フォールバックを実装できます。

以上がvuejsのルーティング実装原理を詳しく解説の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。