安装
$ npm install --save react-router-dom
基本组成
React Router中有三种类型的组件:路由器组件,路由匹配组件和导航组件。
路由器
<BrowserRouter>
:生成的路由是 demo.com/app/index/about<HashRouter>
:生成的路由是 demo.com/#/app/index/about
注意:组件包裹里只能有一个根元素。两者都会history为您创建一个专门的对象。
路由匹配组件
<Route>
:相当于vue 中的 router,但有一点不一样的是vue
中需要router-view
来进行占位渲染,而React
中Route
即是 匹配规则 也是 相当于占位符。path
属性——匹配规则,component
属性——当匹配命中路由时要渲染的组件(必须已有)。render
属性——与component
属性类似,具有内联函数的,仅在必须将范围内的变量传递给要呈现的组件时才应使用。
Switch
:当具有多个<Route>
的时候,常常用<Switch>
进行包裹。<Switch>
将遍历其所有子<Route>
元素,并仅呈现与当前位置匹配的第一个子元素。
注意:
React
路由匹配规则是模糊的,如果想要绝对匹配,可以在Route
中添加一个exact
参数表示绝对匹配。
例:
<Route exact path='/' component={Home}></Route>
<Route exact path='/about' component={About}></Route>
// 上面的 ‘/’ 无论何时都匹配命中,如果我们只想要在 ‘/’ 命中,可以添加 ‘exact’ 属性。
<Route exact path='/home' component={Home}></Route>
导航组件
都具有一个
to
属性,是创建链接。
<Link>
:以<a>
的形式呈现。<NavLink>
:与<Link>
类似,但具有一个activeClassName
, 当处于活跃状态是触发。<Redirect>
:重定向。
路径语法
路由路径是匹配一个(或一部分)URL 的 一个字符串模式。大部分的路由路径都可以直接按照字面量理解,除了以下几个特殊的符号:
:paramName
– 匹配一段位于 /、? 或 # 之后的 URL。 命中的部分将被作为一个参数。可以通props.match.params
(对象)中获取到想要的参数。()
– 在它内部的内容被认为是可选的*
– 匹配任意字符(非贪婪的)直到命中下一个字符或者整个 URL 的末尾,并创建一个 splat 参数。
例:
<Route path="/hello/:name"> // 匹配 /hello/michael 和 /hello/ryan
<Route path="/hello(/:name)"> // 匹配 /hello, /hello/michael 和 /hello/ryan
<Route path="/files/*.*"> // 匹配 /files/hello.jpg 和 /files/path/to/hello.jpg
Match
props.match
包含4个属性:match.params
、match.isExact
、match.path
、match.url
。
当没有参数的时候,match.path 和 match.url 是一样的,而当有参数的时候,两者就有区别了:
- match.path:是指写在 中的 path 参数;
- match.url:是指在浏览器中显示的真实 URL。
建议在写路由路径时使用 match.path
,因为使用 match.url
最终会产生不可预料的场景,如:
const UserComments = ({ match }) => {
console.log(match.params); // output: {}
return <div>UserId: {match.params.userId}</div>
}
const UserSettings = ({ match }) => {
console.log(match.params); // output: {userId: "5"}
return <div>UserId: {match.params.userId}</div>
}
const UserProfilePage = ({ match }) => (
<div>
User Profile:
<Route path={`${match.url}/comments`} component={UserComments} />
<Route path={`${match.path}/settings`} component={UserSettings} />
</div>
)
// 当访问 '/users/5/comments' 时渲染 'UserId: undefined';
// 当访问 '/users/5/settings' 时渲染 'UserId: 5'。
match.path 可用于构造嵌套的 ,而 match.url 可用于构造嵌套的 。
案例Demo
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
import {Link, BrowserRouter, Route, Switch} from "react-router-dom";
class App extends Component {
render() {
return (
<BrowserRouter>
<PrimaryLayout/>
</BrowserRouter>
)
}
}
const PrimaryLayout = () => (
<div className="primary-layout">
<header>
React Router Demo
</header>
<main>
<Link to="/users">login</Link><br/>
<Link to="/about">about</Link>
<Switch>
<Route path="/" exact component={HomePage}/>
<Route path="/users" component={UsersPage}/>
<Route path="/about" component={AboutPage}/>
</Switch>
</main>
</div>
);
const HomePage = () => <div>Home Page</div>
// 查看用户页面
const UsersPage = ({match}) => (
<div>
<aside>
User Page
</aside>
<div>
<Switch>
<Route path={match.path} exact component={BrowseUserTable} />
<Route path={`${match.path}/:userName`} component={UserProfilePage} />
</Switch>
</div>
</div>
)
const BrowseUserTable = ({match}) => (
<ul>
<li><Link to={`${match.path}/bob`}>Bob</Link></li>
<li><Link to={`${match.path}/Tom`}>Tom</Link></li>
<li><Link to={`${match.path}/Jack`}>Jack</Link></li>
</ul>
)
// 用户信息
const UserProfilePage = ({match}) => <div>Hello {match.params.userName}</div>
// 关于
const AboutPage = () => <div>About Page</div>
ReactDOM.render(<App></App>, document.getElementById('root'));