我是爬行者 發表於 2020-4-19 23:02:00

React路由之BrowserRouter实现原理

<h1>一、路由用法</h1>
<p><span style="font-size: 18px">1.安装路由库</span></p>
<p><span style="font-size: 18px">npm i&nbsp;react-router-dom</span></p>
<p><span style="font-size: 18px">2.引入</span></p>
<div><span style="font-size: 18px">import&nbsp;{HashRouter&nbsp;as&nbsp;Router,&nbsp;Route}&nbsp;from&nbsp;'react-router-dom'&nbsp;//路由库</span></div>
<div><span style="font-size: 18px">3.使用</span></div>
<div><span style="font-size: 18px">index.js</span></div>
<div>
<div class="cnblogs_code">
<pre><span style="font-size: 18px">import React from "react"<span style="color: rgba(0, 0, 0, 1)">;
import ReactDOM from </span>"react-dom"<span style="color: rgba(0, 0, 0, 1)">;
import {HashRouter as Router, Route} from </span>'react-router-dom' <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">路由库</span>
import Home from './components/Home'<span style="color: rgba(0, 0, 0, 1)">
import User from </span>'./components/User'<span style="color: rgba(0, 0, 0, 1)">
import Profile from </span>'./components/Profile'
<span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">*
* Router是路由容器
* Route是路由规则,一个Route代表一个路由规则
* path 代表路径 component代表要渲染的组件
</span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
ReactDOM.render(
</span>&lt;Router&gt;
    &lt;Route path="/" component={Home}&gt;&lt;/Route&gt;
    &lt;Route path="/user" component={User}&gt;&lt;/Route&gt;
    &lt;Route path="/profile" component={Profile}&gt;&lt;/Route&gt;
&lt;/Router&gt;,document.getElementById('root')
)</span></pre>
</div>
<p><span style="font-size: 18px">Home组件 Home.js</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px">import React from "react"<span style="color: rgba(0, 0, 0, 1)">;

export </span><span style="color: rgba(0, 0, 255, 1)">default</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(props) {
    console.log(props)
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
      </span>&lt;div&gt;Home&lt;/div&gt;
<span style="color: rgba(0, 0, 0, 1)">    )
}</span></span></pre>
</div>
<p><span style="font-size: 18px">Profile组件 Profile.js</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px">import React from "react"<span style="color: rgba(0, 0, 0, 1)">;

export </span><span style="color: rgba(0, 0, 255, 1)">default</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(props) {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
      </span>&lt;div&gt;Profile&lt;/div&gt;
<span style="color: rgba(0, 0, 0, 1)">    )
}</span></span></pre>
</div>
<p><span style="font-size: 18px">User组件 User.js</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px">import React from "react"<span style="color: rgba(0, 0, 0, 1)">;

export </span><span style="color: rgba(0, 0, 255, 1)">default</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)">(props) {
    </span><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> (
      </span>&lt;div&gt;User&lt;/div&gt;
<span style="color: rgba(0, 0, 0, 1)">    )
}</span></span></pre>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 18px">根据路径渲染组件component</span></p>
<p><span style="font-size: 18px"><img src="https://img2020.cnblogs.com/blog/1843694/202004/1843694-20200419173029908-675838768.png">&nbsp;&nbsp;<img src="https://img2020.cnblogs.com/blog/1843694/202004/1843694-20200419173103139-364582307.png"></span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;可以看到不管是渲染哪个组件,path=“/”的这个路径对应的组件都会渲染出来,这是因为react在渲染的时候会匹配只要是/结尾的,都会渲染出来,要想过滤掉这个home,可以添加一个exact,这个时候在渲染别的组件的时候就不会再渲染了。</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px"><span style="color: rgba(0, 0, 0, 1)">ReactDOM.render(
</span>&lt;Router&gt;
    &lt;Route <span style="color: rgba(255, 0, 0, 1)">exact</span> path="/" component={Home}&gt;&lt;/Route&gt;
    &lt;Route path="/user" component={User}&gt;&lt;/Route&gt;
    &lt;Route path="/profile" component={Profile}&gt;&lt;/Route&gt;
&lt;/Router&gt;,document.getElementById('root')
)</span></pre>
</div>
<p><span style="font-size: 18px">打印props属性:</span></p>
<p><span style="font-size: 18px"><img src="https://img2020.cnblogs.com/blog/1843694/202004/1843694-20200419193238468-1035799480.png"></span></p>
<p>&nbsp;</p>
<ul>
<li><span style="font-size: 18px">length表示当前的路由条目,只有前进的时候才会增加条目,后退并不会增加条目数</span></li>
<li><span style="font-size: 18px">&nbsp;action表示当前路径是通过push来的还是pop来的</span></li>
<li><span style="font-size: 18px">block表示阻止跳转,prompt表示弹出提示是否进行跳转。</span></li>
<li><span style="font-size: 18px">createHref,location对象转换成字符串或者将字符产转换成location对象。</span></li>
<li><span style="font-size: 18px">&nbsp;go 表示跳几步,goBack表示向后跳,goForward表示向前跳</span></li>
<li><span style="font-size: 18px">location 代表当前的路径对象</span></li>
</ul>
<p><span style="font-size: 18px">&nbsp;接下来实现一个自己的路由库。</span></p>
<p><span style="font-size: 18px">React的路由库是借助window.history对象实现的,所以我们今天的实现是需要基于window.history来实现。</span></p>
<p><span style="font-size: 18px">先来了解一下history:</span></p>
<div>
<div>
<p><span style="font-size: 18px">history 有三种实现方式:</span><br><span style="font-size: 18px">
1、createBrowserHistory:用于支持 HTML5 历史记录 API 的现代 Web 浏览器(请参阅跨浏览器兼容性)</span><br><span style="font-size: 18px">
2、createHashHistory:用于旧版Web浏览器</span><br><span style="font-size: 18px">
3、createMemoryHistory:用于node环境下。</span></p>
<p><span style="font-size: 18px">history对象的内部基础方法:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px"><span style="color: rgba(0, 0, 255, 1)">return</span><span style="color: rgba(0, 0, 0, 1)"> {
    listenBefore, </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 内部的hook机制,可以在location发生变化前执行某些行为,AOP的实现</span>
    listen, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> location发生改变时触发回调</span>
    transitionTo, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 执行location的改变</span>
    push, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 改变location</span>
<span style="color: rgba(0, 0, 0, 1)">    replace,
    go,
    goBack,
    goForward,
    createKey, </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建location的key,用于唯一标示该location,是随机生成的</span>
<span style="color: rgba(0, 0, 0, 1)">    createPath,
    createHref,
    createLocation, </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 创建location</span>
}</span></pre>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 18px">以上三种实现方法,都是在history内部方法的基础上进行了改写(覆盖)。</span></p>
<h1>二、路由实现</h1>
<p><strong><span style="font-size: 18px">1、createBrowserHistory</span></strong></p>
</div>
<div class="cnblogs_code">
<pre><span style="font-size: 18px">export <span style="color: rgba(0, 0, 255, 1)">default</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> createBrowserHistory(){
    const globalHistory </span>=<span style="color: rgba(0, 0, 0, 1)"> window.history
    const initialLocation </span>=<span style="color: rgba(0, 0, 0, 1)"> {
      pathname:window.location.pathname,
      state:globalHistory.state </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">历史对象上的状态</span>
<span style="color: rgba(0, 0, 0, 1)">    }
    const history </span>=<span style="color: rgba(0, 0, 0, 1)"> {
      length: globalHistory.length,
      action: </span>"POP", <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当前路径是通过push、pop、replace哪个方法来的</span>
<span style="color: rgba(0, 0, 0, 1)">      location: initialLocation,
      createHref, </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">通过location得到一个字符串</span>
      push, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 改变location 添加新条目</span>
      replace, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">新路径替换当前条目</span>
<span style="color: rgba(0, 0, 0, 1)">      go,
      goBack,
      goForward,
      block,
      listen </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">监听路由变化</span>
<span style="color: rgba(0, 0, 0, 1)">    };
    retrun history
}</span></span></pre>
</div>
<p><span style="font-size: 18px">整体代码是这样的,下面主要看看里面每个方法的实现</span></p>
<p><strong><span style="font-size: 18px">1.1createHref() </span></strong></p>
<p><span style="font-size: 18px">这个方法是根据当前history对象返回一个转换后的字符串</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px"><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> createHref (location) {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> location.protocol + location.host + location.pathname + location.search +<span style="color: rgba(0, 0, 0, 1)"> location.hash
    }</span></span></pre>
</div>
<p><strong><span style="font-size: 18px">1.2.push方法 </span></strong></p>
<p><span style="font-size: 18px">用于路由跳转的方法</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px"><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> setState (state) {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。</span>
      Object.assign(history, state) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">把action,location覆盖到对应的history对象的值</span>
      history.length =<span style="color: rgba(0, 0, 0, 1)"> globalHistory.length
    }
    </span><span style="color: rgba(0, 0, 255, 1)">function</span> push (path,state) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">path新的路径 state 新的状态</span>
      const action = 'PUSH' <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">改变action的值</span>
      const location = {push, state} <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">新的对象</span>
      globalHistory.pushState(state,<span style="color: rgba(0, 0, 255, 1)">null</span>,path) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">调用history的pushState方法实现跳转</span>
      setState({action,location}) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">setState这个setState并不是react自带的setState方法,</span>
<span style="color: rgba(0, 0, 0, 1)">
    }</span></span></pre>
</div>
<p><strong><span style="font-size: 18px">1.3.listen方法</span></strong></p>
<p><span style="font-size: 18px">监听路由的变化</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px"><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> setState (state) {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。</span>
      Object.assign(history, state) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">把action,location覆盖到对应的history对象的值</span>
      history.length =<span style="color: rgba(0, 0, 0, 1)"> globalHistory.length
      listeners.forEach(listener </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> listener())
    }
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> listeners=<span style="color: rgba(0, 0, 0, 1)"> []
    </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> listen (listener) {
      listeners.push(listener)
    }</span></span></pre>
</div>
<p><strong><span style="font-size: 18px">1.4.replace 方法</span></strong></p>
<p><span style="font-size: 18px"> 替换当前路径</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px"><span style="color: rgba(0, 0, 255, 1)">function</span> replace (path,state) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">path新的路径 state 新的状态</span>
      const action = 'REPLACE' <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">改变action的值</span>
      const location = {push, state} <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">新的对象</span>
      globalHistory.replaceState(state,<span style="color: rgba(0, 0, 255, 1)">null</span>,path) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">调用history的replaceState方法实现跳转</span>
      setState({action,location}) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">setState这个setState并不是react自带的setState方法,</span>
<span style="color: rgba(0, 0, 0, 1)">    }

</span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> setState (state) {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。</span>
      Object.assign(history, state) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">把action,location覆盖到对应的history对象的值</span>
      history.length =<span style="color: rgba(0, 0, 0, 1)"> globalHistory.length </span><span style="color: rgba(0, 0, 0, 1)">
    }</span></span></pre>
</div>
<p><span style="font-size: 18px"><strong>5.go() goBack() goForward()</strong></span></p>
<p><span style="font-size: 18px">go表示跳转几步</span></p>
<div><span style="font-size: 18px">goBack表示向后退一步跳转</span></div>
<div>
<div><span style="font-size: 18px">goForward表示向前一步跳转</span></div>
<div>
<div class="cnblogs_code">
<pre><span style="font-size: 18px"><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> go (n) {
      globalHistory.go(n) </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">调用原始的go方法</span>
<span style="color: rgba(0, 0, 0, 1)">    }
    </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> goBack () {
      go(</span>-1<span style="color: rgba(0, 0, 0, 1)">)
    }
    </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> goForward () {
      go(</span>1<span style="color: rgba(0, 0, 0, 1)">)
    }</span></span></pre>
</div>
<p><strong><span style="font-size: 18px">6.block</span></strong></p>
<p><span style="font-size: 18px">表示询问是否跳转</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px">let isBlock <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">是否跳转</span>
    <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> block (prompt) {
      isBlock </span>=<span style="color: rgba(0, 0, 0, 1)"> prompt
    }</span></span></pre>
</div>
<p><span style="font-size: 18px">全部实现:</span></p>
<div class="cnblogs_code">
<pre><span style="font-size: 18px">export <span style="color: rgba(0, 0, 255, 1)">default</span> <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> createBrowserHistory(){
    const globalHistory </span>=<span style="color: rgba(0, 0, 0, 1)"> window.history
    const initialLocation </span>=<span style="color: rgba(0, 0, 0, 1)"> {
      pathname:window.location.pathname,
      state:globalHistory.state </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">历史对象上的状态</span>
<span style="color: rgba(0, 0, 0, 1)">    }
    </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> createHref (location) {
      </span><span style="color: rgba(0, 0, 255, 1)">return</span> location.protocol + location.host + location.pathname + location.search +<span style="color: rgba(0, 0, 0, 1)"> location.hash
    }
    </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> setState (state) {
      </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">Object.assign() 方法用于将所有可枚举属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。</span>
      Object.assign(history, state) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">把action,location覆盖到对应的history对象的值</span>
      history.length =<span style="color: rgba(0, 0, 0, 1)"> globalHistory.length
      listeners.forEach(listener </span>=&gt;<span style="color: rgba(0, 0, 0, 1)"> listener())
    }
    </span><span style="color: rgba(0, 0, 255, 1)">var</span> listeners=<span style="color: rgba(0, 0, 0, 1)"> []
    </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> listen (listener) {
      listeners.push(listener)
    }
    </span><span style="color: rgba(0, 0, 255, 1)">function</span> push (path,state) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">path新的路径 state 新的状态</span>
      const action = 'PUSH' <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">改变action的值</span>
      const location = {push, state} <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">新的对象</span>
      globalHistory.pushState(state,<span style="color: rgba(0, 0, 255, 1)">null</span>,path) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">调用history的pushState方法实现跳转</span>
      setState({action,location}) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">setState这个setState并不是react自带的setState方法,</span>
<span style="color: rgba(0, 0, 0, 1)">    }
    </span><span style="color: rgba(0, 0, 255, 1)">function</span> replace (path,state) { <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">path新的路径 state 新的状态</span>
      const action = 'REPLACE' <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">改变action的值</span>
      const location = {push, state} <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">新的对象</span>
      globalHistory.replaceState(state,<span style="color: rgba(0, 0, 255, 1)">null</span>,path) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">调用history的replaceState方法实现跳转</span>
      setState({action,location}) <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">setState这个setState并不是react自带的setState方法,</span>
<span style="color: rgba(0, 0, 0, 1)">    }
    </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> go (n) {
      globalHistory.go(n) </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">调用原始的go方法</span>
<span style="color: rgba(0, 0, 0, 1)">    }
    </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> goBack () {
      go(</span>-1<span style="color: rgba(0, 0, 0, 1)">)
    }
    </span><span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> goForward () {
      go(</span>1<span style="color: rgba(0, 0, 0, 1)">)
    }
    let isBlock </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">是否跳转</span>
    <span style="color: rgba(0, 0, 255, 1)">function</span><span style="color: rgba(0, 0, 0, 1)"> block (prompt) {
      isBlock </span>=<span style="color: rgba(0, 0, 0, 1)"> prompt
    }
    const history </span>=<span style="color: rgba(0, 0, 0, 1)"> {
      length: globalHistory.length,
      action: </span>"POP", <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">当前路径是通过push、pop、replace哪个方法来的</span>
<span style="color: rgba(0, 0, 0, 1)">      location: initialLocation,
      createHref, </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">通过location得到一个字符串</span>
      push, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)"> 改变location 添加新条目</span>
      replace, <span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">新路径替换当前条目</span>
<span style="color: rgba(0, 0, 0, 1)">      go,
      goBack,
      goForward,
      block,
      listen </span><span style="color: rgba(0, 128, 0, 1)">//</span><span style="color: rgba(0, 128, 0, 1)">监听路由变化</span>
<span style="color: rgba(0, 0, 0, 1)">    };
}</span></span></pre>
</div>
<p>&nbsp;</p>
<p><span style="font-size: 18px">总结:</span></p>
<p><span style="font-size: 18px">react-router是在history基础上实现了URL与UI的同步,其中URL对应的是location,UI对应的是react component。</span></p>
</div>
</div>
<p><span style="font-size: 18px">&nbsp;下篇我们实现一下HashRouter。</span></p>
</div>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
<p><span style="font-size: 18px">&nbsp;</span></p>
</div>

</div>
<div id="MySignature" role="contentinfo">
    不积跬步无以至千里<br><br>
来源:https://www.cnblogs.com/lyt0207/p/12732421.html
頁: [1]
查看完整版本: React路由之BrowserRouter实现原理