08.路由

作者: 阿九是只大胖喵 | 来源:发表于2017-12-07 09:27 被阅读0次

    react-router-4官方文档
    demo的github源码地址
    URL
    一个URL可以定位到网络上的指定资源。一个典型URL结构如下:

    url.jpeg

    虽然protocol和hostname的组合可以直接让我们访问特定的网站,但是pathname则代表的是这个网站上的指定资源。

    举个例子,看看如下的一个访问音乐网站的URL
    https://example.com.com/artists/87589/albums/1758221

    这个地址可以访问特定艺术家的专辑。该URL包含了艺术家以及它的专辑的标识符:
    example.com/artists/:artistId/albums/:albumId

    在一个传统的,只有很少的JavaScript的页面应用中,对网页访问的请求流程大致如下:

    1. 浏览器要访问页面,向服务器发送请求
    2. 服务器根据URL中的标识符从数据库中获取artist和album的数据
    3. 服务器将获取后的数据拼接成模板
    4. 服务器返回模板字符串,并且返回其关联的资源文件,例如CSS文件和图片文件等
    5. 浏览器将得到的资源渲染

    当我们使用React,我们想要React来生成这样的页面。所以,使用React的请求流程就会大致如下:

    1. 浏览器要访问页面,向服务器发送请求
    2. 服务器不关心pathname。取而代之的是,它仅仅返回一个标准的index.html,其中包含了React app和其他静态资源文件
    3. React app 挂载
    4. React app抽取出URL中标识符,并且使用这些标识符来生成API调用以从artist和album中获取数据
    5. React根据API调用后抓取的数据渲染页面

    单页应用(Single-page applications/ SPA)是加载一次然后通过JavaScript动态更新页面上的元素的应用。React通过路由能够很容易的实现单页应用。


    实现
    首先生成我们的demo,一个新闻页面切换的app
    create-react-app react-router-demo
    并且成功运行项目。
    目录结构如下:

    content.jpeg

    要使用React的路由功能,需要安装依赖react-router。这里我们使用第四个版本的 react-router
    安装依赖:
    yarn add react-router-dom
    或者
    npm install --save react-router-dom

    在router.js中:

    import React from 'react';
    import {BrowserRouter, Route, Link} from 'react-router-dom'
    
    import News from '../components/News'
    import NBA from '../components/NBA'
    import Economics from '../components/Economic'
    
    const router = (
      <BrowserRouter>
        <div>
          <h2>news app</h2>
          <ul>
            <li>
              <Link to="/">news</Link>
            </li>
            <li>
              <Link to="/nba">nba</Link>
            </li>
            <li>
              <Link to="/economics">economics</Link>
            </li>
          </ul>
          <Route path="/" component={News} exact></Route>
          <Route path="/nba" component={NBA}></Route>
          <Route path="/economics" component={Economics}></Route>
        </div>
      </BrowserRouter>
    )
    
    export default router
    

    然后点击对应的链接就能切换响应的页面了。
    现在需要点击对应的链接后,能够有一个显示点击后的效果。这个时候就需要使用NavLink了。
    如下:

        <style>
          .is-active {
            font-weight: bold;
            color: deepskyblue;
          }
        </style>
    
    const router = (
      <BrowserRouter>
        <div>
          <h2>news app</h2>
          <ul>
            <li>
              <NavLink to="/" activeClassName="is-active" exact>news</NavLink>
            </li>
            <li>
              <NavLink to="/nba" activeClassName="is-active">nba</NavLink>
            </li>
            <li>
              <NavLink to="/economics" activeClassName="is-active">economics</NavLink>
            </li>
          </ul>
          <Route path="/" component={News} exact></Route>
          <Route path="/nba" component={NBA}></Route>
          <Route path="/economics" component={Economics}></Route>
        </div>
      </BrowserRouter>
    )
    

    这样,点击对应的链接后,该链接会显示style中的样式。

    当用户输入错了URL地址,我们希望能够跳转到一个页面不存在的通用的页面。我们新建一个NotFound的组件,再在路由中是 Switch。表示只要匹配到第一个就跳转到对应组件。

    const router = (
      <BrowserRouter>
        <div>
          <h2>news app</h2>
          <ul>
            <li>
              <NavLink to="/" activeClassName="is-active" exact>news</NavLink>
            </li>
            <li>
              <NavLink to="/nba" activeClassName="is-active">nba</NavLink>
            </li>
            <li>
              <NavLink to="/economics" activeClassName="is-active">economics</NavLink>
            </li>
          </ul>
          <Switch>
            <Route path="/" component={News} exact></Route>
            <Route path="/nba" component={NBA}></Route>
            <Route path="/economics" component={Economics}></Route>
            <Route component={NotFound}></Route>
          </Switch>
        </div>
      </BrowserRouter>
    )
    

    这样,当用户虽然输入一个URL地址后,只要没有匹配到前面的路由地址,那么就会跳转到NotFound页面。


    路由参数
    当我们想要访问一个新闻列表的页面,新闻列表中有很多个新闻,我们点击其中的新闻,则URL地址可能如下:
    localhost:3000/news/1
    localhost:3000/news/2
    localhost:3000/news/3

    当有大量新闻的时候,为每个新闻都写一个组件显然是不显示的。这时候就可以使用路由参数。

    router.js

    const router = (
      <BrowserRouter>
        <div>
          <h2>news app</h2>
          <ul>
            <li>
              <NavLink to="/" activeClassName="is-active" exact>news</NavLink>
            </li>
            <li>
              <NavLink to="/nba" activeClassName="is-active">nba</NavLink>
            </li>
            <li>
              <NavLink to="/economics" activeClassName="is-active">economics</NavLink>
            </li>
          </ul>
          <Switch>
            <Route path="/" component={News} exact></Route>
            <Route path="/nba" component={NBA}></Route>
            <Route path="/economics" component={Economics}></Route>
            <Route path="/newslist/:id" component={NewsList}></Route>
            <Route component={NotFound}></Route>
          </Switch>
        </div>
      </BrowserRouter>
    )
    

    NewsList.js

    class NewsList extends Component {
      render () {
        return (
          <div>
            newslist-item {this.props.match.params.id}
          </div>
        )
      }
    }
    

    这样,主要输入形如如下的网址,那么就可以切换到不同的NewsList中的新闻了:
    localhost:3000/news/id

    相关文章

      网友评论

          本文标题:08.路由

          本文链接:https://www.haomeiwen.com/subject/lugrixtx.html