シングルページアプリケーションの特徴「前提:」Web ページには、クリックするとサイト内の他のページにジャンプできるボタンがあります。 「マルチページ アプリケーション:」 ボタンをクリックして HTML リソースを再読み込みし、ページ全体を更新します。 「シングルページ アプリケーション:」 ボタンをクリックすると、新しい HTML リクエストは発生せず、部分的な更新のみが発生するため、シルクのようにスムーズなネイティブに近いエクスペリエンスを実現できます。 SPA シングルページ アプリケーションがほとんど更新不要で済むのはなぜですか? SP(シングルページ)だから。アプリケーションに初めてアクセスすると、HTML ページとそのパブリック静的リソースのみが返されます。その後のいわゆる「ジャンプ」では、サーバーから HTML ファイルを取得することはなくなり、シミュレートされた DOM 置換操作のみになります。 では、js はどのようにしてコンポーネントの切り替えのタイミングをキャプチャし、更新せずにブラウザの URL を変更するのでしょうか?ハッシュと HTML5History に依存します。 ハッシュルーティング特徴
原理 ハッシュ HTML5履歴ルーティング 特徴
原理 HTML5の歴史 Vue-router ソースコード解釈Vue のルーター vue-router を例に、そのソースコードを見てみましょう。 ヒント: この記事の焦点はシングルページ ルーティングの 2 つのモードを説明することであるため、主に次の内容を説明するいくつかのキー コードのみを以下にリストします。
プラグインの登録 まず、プラグインとして、Vue が使用できるようにインストール メソッドを意識的に公開する必要があります。 ソースコードの install.js ファイルでは、プラグインを登録してインストールするための install メソッドが定義されており、このメソッドは各コンポーネントのフック関数にミックスされ、beforeCreate フックの実行時にルートが初期化されます。 Vue.mixin({ 作成前() { if (isDef(this.$options.router)) { this._routerRoot = これ this._router = this.$options.router this._router.init(これ) Vue.util.defineReactive(this, '_route', this._router.history.current) } それ以外 { this._routerRoot = (this.$parent && this.$parent._routerRoot) || this } インスタンスを登録します(これ、これ) }, // テキスト全体を通じて、... は省略されたメソッドを示すために使用されます... }); 区別モード 次に、index.js からプラグイン全体の基本クラス VueRouter を見つけます。モードに応じてコンストラクターで異なるルーティングインスタンスが使用されていることは簡単にわかります。 ... './install' から {install} をインポートします。 './history/hash' から {HashHistory} をインポートします。 './history/html5' から {HTML5History} をインポートします。 ... デフォルトクラスVueRouterをエクスポートします。 静的インストール: () => void; コンストラクタ(オプション:RouterOptions = {}){ if (this.fallback) { モード = 'ハッシュ' } ブラウザ内で モード = '抽象' } this.mode = モード スイッチ(モード){ ケース「履歴」: this.history = 新しい HTML5History(this、options.base) 壊す ケース 'ハッシュ': this.history = 新しい HashHistory(this、options.base、this.fallback) 壊す ケース「抽象」: this.history = 新しい AbstractHistory(this、options.base) 壊す デフォルト: process.env.NODE_ENV !== 'production' の場合 { assert(false, `無効なモード: ${mode}`) } } } } ルータリンクコンポーネントをグローバルに登録する この時点で、次のような疑問が湧くかもしれません。vue-router を使用する場合、共通の <router-link/> と <router-view/> はどこで導入されるのでしょうか? install.js ファイルに戻ると、router-view および router-link コンポーネントをインポートしてグローバルに登録します。 './components/view' から View をインポートします。 './components/link' から Link をインポートします。 ... Vue.component('RouterView', ビュー); Vue.component('RouterLink', リンク); ./components/link.js では、クリック イベントはデフォルトで <router-link/> コンポーネントにバインドされており、クリックによってハンドラー メソッドがトリガーされ、対応するルーティング操作が実行されます。 定数ハンドラ = e => { ガードイベントの場合(e) (これを置き換える){ router.replace(場所、noop) } それ以外 { router.push(場所、noop) } } }; 冒頭で述べたように、VueRouter コンストラクターはモードごとに異なる History インスタンスを初期化するため、router.replace と router.push のメソッドも異なります。次に、これら 2 つのモードのソース コードをそれぞれプルダウンします。 ハッシュモードhistory/hash.js ファイルでは、history/base.js の History 基本クラスから継承する HashHistory クラスが定義されています。 実は、これを最初に読んだときは少し疑問に思いました。すでにハッシュ モードになっているのに、なぜ supportsPushState を判断する必要があるのでしょうか? scrollBehavior をサポートするために、history.pushState はキー パラメータを渡すことができ、各 URL 履歴にキーが与えられ、そのキーを使用して各ルートの位置情報を保存することがわかりました。 同時に、プロトタイプにバインドされた setupListeners メソッドは、ハッシュの変更のタイミングをリッスンする役割を担います。HTML5History モードをサポートするブラウザー環境では、popstate イベントをリッスンし、その他のブラウザーでは、hashchange をリッスンします。変更を監視した後、handleRoutingEvent メソッドがトリガーされ、親クラスの transitionTo ジャンプ ロジックが呼び出され、DOM 置換操作が実行されます。 '../util/push-state' から { pushState、replaceState、supportsPushState } をインポートします。 ... エクスポートクラスHashHistoryはHistoryを拡張します{ セットアップリスナー() { ... const ハンドルルーティングイベント = () => { 定数 current = this.current if (!ensureSlash()) { 戻る } // 親クラス History のジャンプメソッドは transitionTo によって呼び出され、ジャンプ後にパスがハッシュ化されます this.transitionTo(getHash(), route => { スクロールをサポートする場合 handleScroll(this.router, ルート, 現在の, true) } プッシュ状態をサポートする場合 ハッシュを置換(ルート.fullPath) } }) } const eventType = supportsPushState ? 'popstate' : 'hashchange' ウィンドウにイベントリスナーを追加します( イベントタイプ、 ルーティングイベントの処理 ) this.listeners.push(() => { window.removeEventListener(イベントタイプ、handleRoutingEvent) }) } プッシュ (場所: RawLocation、onComplete?: Function、onAbort?: Function) { const { current: fromRoute } = this this.transitionTo() は、 位置、 ルート => { pushHash(ルート.fullPath) handleScroll(this.router, ルート, fromRoute, false) onComplete && onComplete(ルート) }, 中止時 ) } } ... // 受信したパスをハッシュ化された URL に処理します 関数 getUrl (パス) { 定数 href = window.location.href 定数 i = href.indexOf('#') 定数基数 = i >= 0 ? href.slice(0, i) : href `${base}#${path}` を返します } ... // ハッシュを置き換える 関数pushHash(パス){ (PushStateをサポートする)の場合{ pushState(getUrl(パス)) } それ以外 { window.location.hash = パス } } //util/push-state.js ファイル内のメソッド export const supportsPushState = ブラウザ内 && (関数 () { 定数 ua = window.navigator.userAgent もし ( (ua.indexOf('Android 2.') !== -1 || ua.indexOf('Android 4.0') !== -1) && ua.indexOf('モバイルSafari') !== -1 && ua.indexOf('Chrome') === -1 && ua.indexOf('Windows Phone') === -1 ){ 偽を返す } window.history を返します && typeof window.history.pushState === 'function' })() HTML5履歴モード 同様に、HTML5History クラスは history/html5.js で定義されています。 プッシュ プロトタイプ メソッドを定義し、history.pusheState を呼び出してブラウザー パスを変更します。 同時に、プロトタイプの setupListeners メソッドは popstate イベントを監視し、タイムリーに DOM の置換を行います。 '../util/push-state' から {pushState、replaceState、supportsPushState} をインポートします。 ... エクスポートクラス HTML5History は History を拡張します { セットアップリスナー() { const ハンドルルーティングイベント = () => { 現在の状態を定数で表す。 定数 location = getLocation(this.base); if (this.current === START && location === this._startLocation) { 戻る } this.transitionTo(場所、ルート => { スクロールをサポートする場合 handleScroll(ルーター、ルート、現在、true) } }) } window.addEventListener('popstate', handleRoutingEvent) this.listeners.push(() => { window.removeEventListener('popstate', handleRoutingEvent) }) } プッシュ (場所: RawLocation、onComplete?: Function、onAbort?: Function) { const { current: fromRoute } = this this.transitionTo(場所、ルート => { pushState(cleanPath(this.base + route.fullPath)) handleScroll(this.router, ルート, fromRoute, false) onComplete && onComplete(ルート) }, 中止時) } } ... //util/push-state.js ファイルのメソッドエクスポート function pushState (url?: string, replace?: boolean) { スクロール位置を保存します。 定数履歴 = window.history 試す { (置換)の場合{ const stateCopy = extend({}, history.state) stateCopy.key = getStateKey() history.replaceState(stateCopy, ''、url) } それ以外 { history.pushState({ キー: setStateKey(genStateKey()) }, '', url) } } キャッチ (e) { window.location[replace ? 'replace' : 'assign'](url) } } transitionToはルート変更ロジックを処理します 上記の 2 つのルーティング モードはどちらも、リッスン時に this.transitionTo をトリガーします。これは何ですか?これは実際には history/base.js 基本クラスで定義されたプロトタイプ メソッドであり、ルーティング変更ロジックを処理するために使用されます。 まず、const route = this.router.match(location, this.current) を使用して、渡された値と現在の値を比較し、対応するルート オブジェクトを返します。次に、新しいルートが現在のルートと同じかどうかを判断します。同じ場合は、直接返します。同じでない場合は、this.confirmTransition でコールバックを実行してルート オブジェクトを更新し、ビュー関連の DOM を置き換えます。 エクスポートクラス履歴{ ... 遷移先 ( 場所: RawLocation、 onComplete?: 関数、 onAbort?: 関数 ){ const ルート = this.router.match(場所、this.current) this.confirmTransition() は、 ルート、 () => { 定数 prev = this.current this.updateRoute(ルート) onComplete && onComplete(ルート) this.ensureURL() this.router.afterHooks.forEach(フック => { フック && フック(ルート、前) }) 準備ができたら this.ready = true this.readyCbs.forEach(cb => { cb(ルート) }) } }, エラー => { 中止の場合 中止(エラー) } もしエラーなら、this.ready です。 this.ready = true // https://github.com/vuejs/vue-router/issues/3225 if (!isRouterError(err, NavigationFailureType.redirected)) { this.readyErrorCbs.forEach(cb => { cb(エラー) }) } それ以外 { this.readyCbs.forEach(cb => { cb(ルート) }) } } } ) } ... } やっとさて、以上はシングルページルーティングに関するちょっとした知識です。始めから諦めずに続けられるといいですね~~ これで、WeChatミニプログラムシングルページアプリケーションルーティングを10分で徹底的に理解する方法に関する記事は終了です。より関連性の高いミニプログラムシングルページアプリケーションルーティングコンテンツについては、123WORDPRESS.COMで以前の記事を検索するか、次の関連記事を引き続き閲覧してください。今後とも123WORDPRESS.COMを応援してください。 以下もご興味があるかもしれません:
|
<<: Linux デュアル ネットワーク カード バインディング スクリプト メソッドの例
>>: MySQLは既存のコンテンツを保持し、後でコンテンツを追加します
トムキャット公式サイトtomcatはローカルサーバーと同等であり、Webページを開くことができます設...
コードをコピーコードは次のとおりです。 <スタイル タイプ="text/css&qu...
目次URL モジュール1. 解析メソッド2. フォーマット方法3. 解決方法イベントモジュール(イベ...
この記事では、シンプルな HTML ビデオ プレーヤーを実装する方法を紹介し、皆さんと共有します。詳...
1. リストシンボルを設定するlist-style-type: attribute; //リストの...
目次render.js 部分create-context.js 部分差分部分Reactのソースコード...
目次# データ準備後# SQLクエリ率テスト# SQL グループレートテスト# sql ソート率テス...
以下は、Flex レイアウトを使用した棒グラフです。 HTML: <div class=&qu...
目次プロジェクト紹介:プロジェクトディレクトリ: TabBar 効果のプレビュー: TabBar 実...
Windows を例にとると、Linux も実際には同じです。静的リソースサーバーを構築するパソコン...
目次概要コールバックまたは高階関数とは何ですか?コールバック関数はどのように機能しますか?コールバッ...
Linux の /etc/network/interfaces ファイルは、ネットワーク インターフ...
Linux 仮想マシン: VMware + Ubuntu 16.04.4 Windows ネイティブ...
1. 内部結合クエリの概要内部結合は、アプリケーションで非常に一般的な結合操作であり、通常はデフォ...
HTML では、<、>、& などは特別な意味を持ち (<、> はリン...