ReactRouterの実装
説明する
ブラウザ履歴
位置 / { try_files $uri $uri/ /index.html; } ハッシュ履歴
記憶の履歴
定数履歴 = createMemoryHistory(場所); 成し遂げる非常にシンプルな <!-- ブラウザ履歴 --> <!DOCTYPE html> <html lang="ja"> <ヘッド> <メタ文字セット="UTF-8"> <title>ルーター</title> </head> <本文> <ul> <li><a href="/home" rel="external nofollow" >ホーム</a></li> <li><a href="/about" rel="external nofollow" >について</a></li> <div id="ルートビュー"></div> </ul> </本文> <スクリプト> 関数ルーター() { this.routeView = null; // コンポーネントホストビューコンテナ this.routes = Object.create(null); // 定義されたルート } // ルートマッチングイベントをバインドする Router.prototype.route = function (path, callback) { this.routes[path] = () => this.routeView.innerHTML = callback() || ""; }; // InitializeRouter.prototype.init = function(root, rootView) { this.routeView = rootView; //ビューコンテナを指定する this.refresh(); //ビューを初期化して更新する root.addEventListener("click", (e) => { //ルートへのイベント委譲 if (e.target.nodeName === "A") { e.preventDefault(); history.pushState(null, "", e.target.getAttribute("href")); this.refresh(); // ビューを更新するためのトリガー} }) // ユーザーの「戻る」と「進む」のクリックをリッスンします // pushState と replaceState は popstate イベントをトリガーしません window.addEventListener("popstate", this.refresh.bind(this), false); }; // ビューを更新するRouter.prototype.refresh = function () { path = location.pathname とします。 console.log("更新", パス); this.routes[path] の if(this.routes[path]()); それ以外の場合は this.routeView.innerHTML = ""; }; window.Router = 新しい Router(); Router.route("/home", 関数() { 「ホーム」を返します。 }); Router.route("/about", 関数() { 「about」を返します。 }); Router.init(ドキュメント、document.getElementById("routeView")); </スクリプト> </html> <!-- ハッシュ履歴 --> <!DOCTYPE html> <html lang="ja"> <ヘッド> <メタ文字セット="UTF-8"> <title>ルーター</title> </head> <本文> <ul> <li><a href="#/home" rel="external nofollow" >ホーム</a></li> <li><a href="#/about" rel="external nofollow" >について</a></li> <div id="ルートビュー"></div> </ul> </本文> <スクリプト> 関数ルーター() { this.routeView = null; // コンポーネントホストビューコンテナ this.routes = Object.create(null); // 定義されたルート } // ルートマッチングイベントをバインドする Router.prototype.route = function (path, callback) { this.routes[path] = () => this.routeView.innerHTML = callback() || ""; }; // InitializeRouter.prototype.init = function(root, rootView) { this.routeView = rootView; // ビュー コンテナーを指定します this.refresh(); // 初期化トリガー // 更新するために hashchange イベントをリッスンします window.addEventListener("hashchange", this.refresh.bind(this), false); }; // ビューを更新するRouter.prototype.refresh = function () { ハッシュ = location.hash; console.log("更新", ハッシュ); this.routes[ハッシュ]を返し、this.routes[ハッシュ]を返します。 それ以外の場合は this.routeView.innerHTML = ""; }; window.Router = 新しい Router(); Router.route("#/home", 関数() { 「ホーム」を返します。 }); Router.route("#/about", 関数() { 「about」を返します。 }); Router.init(ドキュメント、document.getElementById("routeView")); </スクリプト> </html> 分析する
// packages\react-router-dom\modules\HashRouter.js 10行目 BrowserRouterクラスはReact.Componentを拡張します。 履歴 = createHistory(this.props); 与える() { <Router history={this.history} children={this.props.children} /> を返します。 } } 次に、 // 行 packages\react-router\modules\Router.js 行 10 クラス Router は React.Component を拡張します { 静的computeRootMatch(パス名) { 戻り値: { パス: "/", url: "/", パラメータ: {}, isExact: パス名 === "/" }; } コンストラクタ(props) { スーパー(小道具); この状態 = { 場所: props.history.location }; // これはちょっとしたハックです。位置情報を聞き始める必要があります // <Redirect> がある場合に備えて、コンストラクタ内で変更します // 初期レンダリング時に。存在する場合は、置き換え/プッシュされます // それらはマウントされ、cDMは親よりも先に子で発火するので、 // <Router> がマウントされる前に新しい場所を取得します。 this._isMounted = false; this._pendingLocation = null; 静的コンテキストの場合 this.unlisten = props.history.listen(location => { if (this._isMounted) { this.setState({ location }); } それ以外 { this._pendingLocation = 場所; } }); } } コンポーネントマウント() { this._isMounted = true; if (this._pendingLocation) { this.setState({ location: this._pendingLocation }); } } コンポーネントのマウントを解除します(){ this.unlisten() は、次の例のように機能します。 } 与える() { 戻る ( <ルーターコンテキスト.プロバイダー children = {this.props.children || null} 値={{ 履歴: this.props.history、 場所: this.state.location、 一致: Router.computeRootMatch(this.state.location.pathname)、 静的コンテキスト: this.props.staticContext }} /> ); } } これを使用するときは、 // \packages\react-router\modules\Route.js 17行目 クラス Route は React.Component を拡張します { 与える() { 戻る ( <ルーターコンテキスト.コンシューマー> {コンテキスト => { invariant(context, "<Router> の外部では <Route> を使用しないでください"); const location = this.props.location || context.location; 定数マッチ = this.props.computedMatch ? this.props.computedMatch // <Switch> はすでに一致を計算しています : this.props.path ? matchPath(location.pathname, this.props) : コンテキストに一致します。 const props = { ...コンテキスト、場所、一致 }; let { children, component, render } = this.props; // Preactは空の配列を子として使用します // デフォルトなので、その場合は null を使用します。 Array.isArray(children) && children.length === 0 の場合 { 子 = null; } if (typeof children === "function") { 子供 = 子供(プロパティ); // ... } 戻る ( <RouterContext.Provider 値 = {props}> {子供 && !isEmptyChildren(子供) ? 子供たち : props.match ? 成分 React.createElement(コンポーネント、プロパティ) : 与える ? レンダリング(props) : ヌル : ヌル} </ルーターコンテキスト.プロバイダー> ); }} </ルーターコンテキスト.コンシューマー> ); } } 実際、おそらく最も多く書くタグは // packages\react-router-dom\modules\Link.js 14行目 クラスLinkはReact.Componentを拡張します。 handleClick(イベント、履歴) { this.props.onClick の場合、 this.props.onClick(イベント); もし ( !event.defaultPrevented && // onClick はデフォルトで禁止 event.button === 0 && // 左クリック以外はすべて無視 (!this.props.target || this.props.target === "_self") && // ブラウザに "target=_blank" などを処理させます。 !isModifiedEvent(event) // 修飾キーによるクリックを無視する ){ イベントをデフォルトにしない(); const メソッド = this.props.replace ? history.replace : history.push; メソッド(this.props.to); } } 与える() { const { innerRef, replace, to, ...rest } = this.props; // eslint-disable-line no-unused-vars 戻る ( <ルーターコンテキスト.コンシューマー> {コンテキスト => { invariant(context, "<Link> を <Router> の外部で使用しないでください"); 定数場所 = typeof を === "string" にする ? createLocation(to, null, null, context.location) : に; const href = location ? context.history.createHref(location): ""; 戻る ( <a {...休む} onClick={イベント => this.handleClick(イベント、コンテキスト.履歴)} href={href} ref={内部参照} /> ); }} </ルーターコンテキスト.コンシューマー> ); } } 毎日の質問 https://github.com/WindrunnerMax/EveryDay 参照する https://zhuanlan.zhihu.com/p/44548552 https://github.com/fi3ework/blog/issues/21 https://juejin.cn/post/6844903661672333326 https://juejin.cn/post/6844904094772002823 https://juejin.cn/post/6844903878568181768 https://segmentfault.com/a/1190000014294604 https://github.com/youngwind/blog/issues/109 http://react-guide.github.io/react-router-cn/docs/guides/basics/Histories.html ReactRouterの実装方法については以上です。ReactRouterの実装方法については、123WORDPRESS.COMの過去記事を検索するか、引き続き以下の関連記事をご覧ください。今後とも123WORDPRESS.COMをよろしくお願いいたします。 以下もご興味があるかもしれません:
|
<<: Linux での MySQL 5.7.16 無料インストール バージョンのグラフィック チュートリアル
>>: Dockerをクリーンアンインストールする方法の詳細な説明
1. ポート2375を開くdocker.serviceを編集する vim /lib/systemd/...
目次並べ替えクエリの最適化変更されたばかりのデータ行を繰り返し取得しないようにする遅延ロードされた結...
1. 環境整備1.MySQLインストールパス: /usr/local 2. CentOS 6.2 ...
序文良い習慣はすべて宝物です。この記事は、SQL の後悔の治療法、SQL パフォーマンスの最適化、S...
昨晩、面接の質問を見ていたら、CSS スタイルの優先順位について特に明確に説明していない人が何人かい...
1. 背景インターネット アプリケーションの急速な更新と反復という状況では、従来の手作業や単純なスク...
私は現在、自分自身の小さなプログラム プロジェクトに取り組んでいます。プロフェッショナルなフロントエ...
この記事では、Vueを使用して虫眼鏡付きの検索ボックスを実装する方法を紹介します。具体的な内容は次の...
序文MySQL のスリープ システム機能は、実用的な適用シナリオが少なく、通常は実験的なテストに使用...
要素 ui テーブルにはドラッグ アンド ドロップによる並べ替え機能が組み込まれておらず、サードパー...
ハイパーリンクはインターネット全体を接続していると言っても過言ではありません。ハイパーリンクは、別の...
タブバー: 異なるタブをクリックすると異なるコンテンツが表示され、クリックしたタブのスタイルが変更さ...
この方法は2021年2月7日に編集されました。私が使用しているバージョンは8.0.23です。事件の原...
目次01. リスナーウォッチ(1)機能(2)特性と方法(3)監視対象(4)リスニングアレイ02. 計...
目次1. Vueリスナー配列2. vueが配列の変更を監視できない状況1. Vueリスナー配列Vue...