React路由
内容大纲:
1、什么是React路由
2、React路由内置组件
3、路由基本使用
4、路由传值
5、嵌套路由
一、什么是React路由
1.1 React路由介绍
使用React构建的单页面应用,要想实现页面间的跳转,首先想到的就是使用路由。
单页面应用
- 单页面得特点:只需要加载一次主页面,通过局部刷新,就可以实现跳转或者切换页面
- 优点:加载速度快,用户体验比较好
- 缺点:第一次加载比传统要慢一点
- 不利seo
- 页面相对复杂
- 返回键
1.2 安装react-router-dom
首先进入项目目录,使用npm安装react-router-dom:
npm install react-router-dom --save-dev // 这里可以使用cnpm代替npm命令
二、React路由内置组件
- HashRouter表示一个路由的根容器,将来所有的路由相关的东西,都要包裹在HashRouter里面,而且一个网站中,只需要使用一次HashRouter就好了;
- Route表示一个路由规则,在Route上,有两个比较重要的属性,path,component
- Link表示一个路由的链接
2.1HashRouter和BrowserRouter的区别;
BrowserRouter:
原理是H5的history API,IE9及以下不兼容,需要由web server支持,在web client这边window.location.pathname被react router解析,example.com/react/route
HashRouter:
原理是URL的hash,不需要由web server支持,因为它的只有‘/’path需要由web server支持,而#/react/route URL不能被web server读取,在web client这边window,location.hash被react router解析,example.com/#/react/route
三、路由基本使用
新建两个页面 分别命名为News Home 在页面编写下面代码
Home.js页面
import React,{Component} from 'react';
export default class Home extends Component{
render(){
return(
<div>
<h2>首页内容</h2>
</div>
)
}
}
News.js页面
import React,{Component} from 'react';
export default class News extends Component{
render(){
return(
<div>
<h2>新闻内容</h2>
</div>
)
}
}
然后再新建一个路由组件,命名为“App.js”,并编写如下代码:
App.js页面
import React from 'react';
import Home from './Home';
import News from './News';
// 引入路由 用到什么组件写进{}中
import {HashRouter,Route,Link} from 'react-router-dom';
class App extends React.Component{
render(){
return(
<HashRouter>
<div>
<h1>这是根目录</h1>
<hr/>
{/* 链接 */}
<Link to="/Home">首页</Link>
<Link to="/news">新闻</Link>
{/* 路由规则,Route是配置路由的规则,同时也是一个占位符*/}
<Route path="/Home" component={Home}></Route><hr/>
{/* exact 准确匹配路径 */}
{/* <Route path="/news" exact component={News}></Route><hr/> */}
<Route path="/news" component={News}></Route>
</div>
</HashRouter>
)
}
}
export default App;
如上代码定义了一个纯路由组件,将两个页面组件Home和News使用App组件包裹,当路由组件检测到地址栏与App的path匹配时,就会自动加载响应的页面。
然后在入口文件中——我这里指定的是index.js——编写如下代码:
index.js页面
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'
ReactDOM.render(<App></App>, document.getElementById('root'));
这里相当于向页面返回了一个路由组件。若在地址栏输入“http://localhost:3000”
页面会显示两个link 点击首页会出现 首页内容 点击新闻会出现 新闻内容
注意:
- Route 组件path地址是以/开头 ,配置component属性,是显示的组件,这个属性不可以大写
- Route组件可以单双标签使用,单标签需要/结尾,双标签不可以在中间写入别的东西
- Link to属性的地址也是/开头,Link在页面渲染的是a标签
四、路由传值
通过配置路由的地址,在Link跳转时
- Route path路径后面 /:id (key)
- Link to 路径后面 /top/10 (value)
接收传值: - class类组件,this.props.match.params.属性名
- 函数组件:形参.match.params.属性名
代码示例:
App.js页面
import React from 'react';
import Home from './Home';
import News from './News';
// 引入路由 用到什么组件写进{}中
import {HashRouter,Route,Link} from 'react-router-dom';
class App extends React.Component{
render(){
return(
<HashRouter>
<div>
<h1>这是根目录</h1>
<hr/>
{/* 链接 */}
<Link to="/Home">首页</Link>
{/* 在Link内置组件中,配置to属性 */}
<Link to="/news/top/1001">新闻</Link>
{/* 路由规则,Route是配置路由的规则,同时也是一个占位符 */}
<Route path="/Home" component={Home}></Route><hr/>
{/* 在Route内置组件中,配置path地址 */}
<Route path="/news/:type/:id" component={News}></Route>
</div>
</HashRouter>
)
}
}
export default App;
News.js页面
import React,{Component} from 'react';
export default class News extends Component{
constructor(props){
super();
this.state={
p : props.match.params
}
}
render(){
return(
<div>
<h2>新闻内容</h2>
{/* 类组件中通过生命周期进行接收,this.props携带路由传递过来的数据 */}
{/* {this.props.match.params.type},{this.props.match.params.id} */}
{/* 优化后的写法 */}
{this.state.p.type},{this.state.p.id}
</div>
)
}
}
优化后的注释在把优化前的放开结果一样
五、嵌套路由
嵌套路由:在路由组件中,使用Link, Route,配置子路由,实现跳转,切换;
代码示例:
App.js页面
import React from 'react';
import Home from './Home';
import News from './News';
// 引入路由 用到什么组件写进{}中
import {HashRouter,Route,Link} from 'react-router-dom';
class App extends React.Component{
render(){
return(
<HashRouter>
<div>
<h1>这是根目录</h1>
<hr/>
{/* 链接 */}
<Link to="/Home">首页</Link>
<Link to="/news">新闻</Link>
{/* 路由规则,Route是配置路由的规则,同时也是一个占位符*/}
<Route path="/Home" component={Home}></Route><hr/>
{/* 下面为一级路由,在 一级路由 News为路由组件 */}
<Route path="/news" component={News}></Route>
</div>
</HashRouter>
)
}
}
export default App;
新建一个页面 命名为Shehui 在页面编写下面代码
Shehui.js页面
import React,{Component} from 'react';
export default class Shehui extends Component{
render(){
return(
<div>
<p>社会新闻内容</p>
</div>
)
}
}
在News组件中继续使用Link,Route进行路由的嵌套,需要注意的就是路由地址,前部分为一级路由地址,后面接一个二级路由相应的路径
News.js页面
import React,{Component} from 'react';
// 引入路由 用到什么组件写进{}中
import {Link,Route} from 'react-router-dom';
// 引入社会组件
import Shehui from './Shehui';
export default class News extends Component{
constructor(props){
super();
this.state={
p : props.match.params
}
}
render(){
return(
<div>
<h2>新闻内容</h2>
{/* <ul>
<li>
<Link to="/news/shehui">社会新闻</Link>
<Route path="/news/shehui" component={Shehui}></Route>
</li>
</ul> */}
{/* 优化后的写法 */}
<Link to={`/news/${this.state.p.type}/${this.state.p.id}/shehui`}>社会新闻</Link>
<Route path='/news/:type/:id/shehui' component={Shehui}></Route>
</div>
)
}
}
若在地址栏输入“http://localhost:3000” , 页面会显示两个link ,点击首页会出现 首页内容 ,
点击新闻会出现 新闻内容和另一个link(超链接)社会新闻,点击社会新闻会出现 社会新闻内容