上节课我们介绍了如去解决样式的丢失问题,这节课我们来讲一下路由的模糊匹配和严格匹配。

回顾

在开始这节课的内容之前,我们来对上节课的内容来做一个简单的回顾。

  • 多级路由路径在刷新时会丢失样式
  • 样式丢失是由导入样式的相对路径导致的
  • 解决样式丢失有三种办法
  • %PUBLIC_URL%引入样式
  • 根目录引入样式
  • HashRouter解决

以上便是上节课的主要内容,接下来我们来介绍路由的模糊匹配与严格匹配。

问题

我们来思考一个问题,如果我们注册路由的时候路径和路由链接里面的路径不一致,那么还能成功匹配吗?

export default class App extends Component {
  render() {
    return (
      <div>
        ...
            <div className="list-group">
              <MyNavLink to="/about">About</MyNavLink>
              <MyNavLink to="/home">Home</MyNavLink>
            </div>
        ...
                <Switch>
                  <Route path="/about" component={About} />
                  <Route path="/home/a" component={Home} />
                </Switch>
        ...
      </div>
    );
  }
}

比如像这样,我们注册路由的时候用的是/home/a,那么我点击Home的时候还能成功匹配出来吗?那我们那事实说话:

image-20220114133421852

我们来看,点击Home的时候是不是什么都没有展示?这是不是意味着我们并没有能够成功匹配?这也很好理解啊,因为我们确实没匹配上嘛,这个路径不一样啊。

模糊匹配

但是如果这样呢?

export default class App extends Component {
  render() {
    return (
      <div>
        ...
            <div className="list-group">
              <MyNavLink to="/about">About</MyNavLink>
              <MyNavLink to="/home/a">Home</MyNavLink>
            </div>
        ...
                <Switch>
                  <Route path="/about" component={About} />
                  <Route path="/home" component={Home} />
                </Switch>
        ...
      </div>
    );
  }
}

这次我给反过来了,我让路由链接的路径为/home/a,注册路由时候的路径用/home,那么这次能成功匹配吗?可能有人要说,嗐,这不一样嘛,两个路径不一样,肯定匹配不上啊。那么我们看看效果:

image-20220114134005574

这次匹配上了。路径也变成了我们路由链接的路径,为什么呢?这就叫模糊匹配。

我们来看,我们路由链接的路径是/home/a,但是我们注册路由的时候的路径是/home,那么路由链接的路径是不是包含了注册路由时候的路径?可能这个时候大家得出一个结论,就是在路由链接的路径中完全包含注册路由时的路径时,便可以完成模糊匹配。但是事实是这样吗?如果这样的话呢?

export default class App extends Component {
  render() {
    return (
      <div>
        ...
            <div className="list-group">
              <MyNavLink to="/about">About</MyNavLink>
              <MyNavLink to="/b/home/a">Home</MyNavLink>
            </div>
        ...
                <Switch>
                  <Route path="/about" component={About} />
                  <Route path="/home" component={Home} />
                </Switch>
        ...
      </div>
    );
  }
}

我路由链接的路径里面也确实是完全包含了注册路由时的路径。那么能不能匹配呢?

image-20220114134844251

虽然路径确实也变了,但是我们并没有能够成功展示出来我们的组件。那么是为什么呢?因为模糊匹配的时候,比如我们路由链接的路径是/home/a,注册的路由路径是/home,那么在底层匹配的时候,/home/a会被拆成[home, a],而/home就是[home],然后再在底层按照顺序匹配,然后发现第一个home匹配上了,那就完成了模糊匹配。但是如果我们路由链接的路径是/b/home/a,底层就会给拆成[b, home, a]/home,在底层中依然是[home],然后再匹配的时候发现bhome不匹配,那么就不再往后看了。所以说我们正确的结论是当我们路由链接的路径完全包含注册路由的路径,而且顺序一致的情况下才能够完成模糊匹配。

严格匹配

我们从上面的例子中可以看出来react默认开启的是模糊匹配,那么有模糊匹配就会有精准匹配。那么怎么开启精准匹配呢?

export default class App extends Component {
  render() {
    return (
      <div>
        ...
            <div className="list-group">
              <MyNavLink to="/about">About</MyNavLink>
              <MyNavLink to="/home/a">Home</MyNavLink>
            </div>
        ...
                <Switch>
                  <Route path="/about" component={About} />
                  <Route exact={true} path="/home" component={Home} />
                </Switch>
        ...
      </div>
    );
  }
}

我们看上面这段代码,我其实也并没有加上面复杂的操作,只是在注册/home的时候加了一个标签属性exact,并且设为了true,那么我们再来看看现在的效果:

image-20220114141242935

这次我们看见当我们点击了Home,然后展示区上面都没有展示,就说明了并没有匹配成功,应为精准匹配就是得路由链接的路径必须和注册路由的路径一模一样才能够匹配成功。另外一点呢,我们其实也不是一定要完整输入exact={true},直接写一个exact就可以达到效果。

以上便是模糊匹配与严格匹配的内容

总结

  • 默认模糊匹配
  • 通过exact属性开启严格匹配

Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.

Link of this article:https://work.lynchow.com/article/fuzzy_precision/