17-react路由匹配

118 阅读3分钟

先说说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,LinkSwitch} 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组件

解决方法:

  1. 加入exact属性,使得path为/home时,输入/home/abc无效,但/home/有效
  2. 加入exact strict属性,使得path为/home时,输入/home/abc与/home/都无效
  3. 加入exact strict属性,当输入/home与/Home是都可以访问到Home组件(无法解决大小写问题
  4. 加入exact strict sensitive,只能严格的输入/home才可以匹配显示组件。(解决了大小写问题