先说说hashrouter与browserRouter的使用。
hashrouter:
npm install --save react-router-dom@5.3.3
注意安装5.3.3哦,因为默认安装6.几是不好用的,太新了。
安装后就可以引用插件中的组件了。
import {HashRouter,Route,Link} from "react-router"
其中Link 和Route必须在HashRoute路由组件中被包裹。
Link组件用于跳转到指定url中。
Route组件用于匹配其自身带的path属性。当地址链接与Route中path吻合时,显示Route内包裹的组件。来看实例:
<HashRouter>
<Link to="/about">About</Link>
// 也可以写成
<a href="#/inbox">inbox</a>
// 注意链接中有无井号哦
</HashRouter>
当url改变时,去对应Route中path的路径加载对应组件:
<Route path="/home">
<Home/>
</Route>
<Route path="/inbox">
<Inbox/>
</Route>
<Route path="/about">
<About/>
</Route>
以上代码可以实现:点击链接,加载对应的组件,但要注意Route组件和Link组件都要包裹在HashRoute中。
BrowserRouter
同理,也是要将Route组件和Link组件放在BrowserRoute组件中使用。
在react-router-dom中已经涵盖了核心包react-router
BrowserRoute是history模式下的容器,Route去定义组件路径path和子元素,一旦路径变化就去渲染组件。
第一种路由匹配:
点击链接,渲染组件
<BrowserRouter>
<Link to="/home">home</Link>
<Route path="/home">
<Home/>
</Route>
</BrowserRouter>
第二种路由匹配:
<BrowserRouter>
<Link to="/home">home</Link>
<Route path="/home" component={Home} />
</BrowserRouter>
第三种路由匹配:
<BrowserRouter>
<Link to="/home">home</Link>
<Route path="/about" render={()=><Home/>} />
</BrowserRouter>
第四种路由匹配:
<BrowserRouter>
<Link to="/home">home</Link>
<Link to="/inbox">inbox</Link>
<Link to="/home">Home</Link>
<Route path="/about" children={()=><Home/>} />
</BrowserRouter>
需要注意,最后一种children,无论当前的路径为什么,它都会显示,即使不是home路径,也会显示Home组件。
再次思考,如果这四种方法都写在了/home的path匹配上上,但是却分别显示不同的组件,那么请问四种方法是否有一个优先级在呢?还是别的情况呢?往下看。
模糊匹配
<BrowserRouter>
<Link to="/home">home</Link>
<Route path="/" component={About} />
<Route path="/home" component={Home} />
</BrowserRouter>
你看啊,不做任何处理时,当路径为/home时,页面显示了两个组件,分别为About组件和Home组件
是不是因为匹配的顺序呢?调换一下再运行。
<BrowserRouter>
<Link to="/home">home</Link>
<Route path="/home" component={Home} />
<Route path="/" component={About} />
</BrowserRouter>
结果还是如此,还是会同时显示两个组件。
这就是模糊匹配。
并且得出结论,模糊匹配与Route顺序无关。
精确匹配
<BrowserRouter>
<Link to="/home">home</Link>
<Route path="/home" component={Home} exact/>
<Route path="/" component={About} exact/>
</BrowserRouter>
当路径是完全匹配/home时,才会显示组件。
switch唯一匹配
import {HashRouter,Route,Link,Switch} from "react-router"
先引入Switch
<BrowserRouter>
<Link to="/home">home</Link>
<Switch>
<Route path="/home" component={Home} />
<Route path="/" component={About} />
</Switch>
</BrowserRouter>
当Route被switch包裹上之后,就可以进行唯一匹配,也就是说当to的路径传入之后,只与Route进行一次匹配就停止了,不再进行下一次匹配了。
如上代码,在没有进行唯一匹配时,/home路径会引发模糊匹配,导致同时匹配到/home与/两个路径,并且显示两个组件。
但是一旦使用Switch包裹上之后,就使得在只匹配到/home后,就停止匹配,成功使得只显示一个home组件。
<BrowserRouter>
<Link to="/home">home</Link>
<Switch>
<Route path="/" component={About} exact/>
<Route path="/home" component={Home} />
</Switch>
</BrowserRouter>
当switch与exact配合使用,则更加精确了显示组件的路径。
在没有加上exact之前,/home会唯一匹配第一个path /,但是加上exact之后,/home就会去匹配第二个Route的path /home,实现了显示home唯一组件。
拓展:
<Route path="/home" component={Home} />
场景:设置/home对应的组件为Home。
思考: 但是如果在url中输入 /home/ 或者 /home/abc是什么结果呢?
答案,无影响,都会显示Home组件
解决方法:
- 加入exact属性,使得path为/home时,输入/home/abc无效,但/home/有效
- 加入exact strict属性,使得path为/home时,输入/home/abc与/home/都无效
- 加入exact strict属性,当输入/home与/Home是都可以访问到Home组件(无法解决大小写问题)
- 加入exact strict sensitive,只能严格的输入/home才可以匹配显示组件。(解决了大小写问题)