08.路由

2017-12-07  本文已影响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

上一篇 下一篇

猜你喜欢

热点阅读