react-路由
react路由 4.x
资料:
API:https://reacttraining.com/react-router/web/guides/quick-start
CN:http://blog.csdn.net/sinat_17775997/article/details/77411324
区别:
V4
嵌套式路由(路由配置在组件内部),动态路由,包容性(多路由渲染)
舍去了路由钩子
V3
分离式(统一位置配置),静态路由,排他性(只有一个路由被渲染)
理念:
遵循Just Component的 API 设计理念 万物皆组件,路由规则位于布局和 UI 本身之间
安装引入 react-router-dom
React Router被拆分成三个包:react-router,react-router-dom和react-router-native。react-router提供核心的路由组件与函数。其余两个则提供运行环境(即浏览器与react-native)所需的特定组件
BrowserRouter 使用 HTML5 提供的 history API 来保持 UI 和 URL 的同步
HashRouter 使用 URL 的 hash (例如:window.location.hash) 来保持 UI 和URL 的同步
依赖安装引入 react-router-dom
提供哪些组件:
BrowserRouter 约定模式 为 history
HashRouter 约定模式 为 hash
NavLink 声明式跳转 还可以约定 路由激活状态 | 导航高亮 ~~ push
Link 声明式跳转 ~~ push
Redirect 重定向 ~~ replace
Route 匹配 ~~ router-view + {path:xx,component}
Switch 排他性匹配
Prompt 后置守卫
结构:
BrowserRouter|HashRouter 路由对象
根组件(App)|其他组件
NavLink|Link 导航
Route 匹配+展示
Redirect 跳转
默认路由 <Route exact path={match.path} render={fuc}
Route 属性
path(string): 路由匹配路径。(没有path属性的Route 总是会 匹配);
exact(bool):
为true时,要求全路径匹配(/home)。V4 的路由默认为“包含”的(/和/home都匹配),这意味着多个 <Route> 可以同时进行匹配和渲染
component:在地址匹配的时候React的组件才会被渲染,route props也会随着一起被渲染
render:这种方式对于内联渲染和包装组件却不引起意料之外的重新挂载特别方便
Link:
to:string/object:要跳转的路径或地址;
NavLink:是<Link> 的一个特定版本
activeClassName(string):设置选中样式,默认值为 active;
activeStyle(object):当元素被选中时, 为此元素添加样式;
Switch:该组件用来渲染匹配地址的第一个<Route>或者<Redirect>,仅渲染一个路由,排他性路由,默认全匹配(场景:侧边栏和面包屑,引导选项卡等
Redirect:
<Redirect from="/" to='/home'/> 总是会被重定向
404: <Route component={Error}/> 总是会匹配
参数数据:{history,location,match}==props
传递:
to={match.url+'/001'}
to={`${match.url}/002?a=1&b=2`}
to={{pathname:match.url+'/003',search:'?a=11&b=12',hash:'#a1'}}
<Route path={match.path+'/:aid'} component={Detail}
注意:
url - (浏览器 URL 中的实际路径) URL 匹配的部分。 用于构建嵌套的 <Link>
path - (路由编写的路径) 用于匹配路径模式。用于构建嵌套的 <Route>
接收:
接参数:{match.params.aid}
接数据:{location.search}
接地址:{location.pathname}
注意:
无法从v4 中获取 URL 的查询字符串了。因为没有关于如何处理复杂查询字符串的标准。所以,作者让开发者去选择如何处理查询字符串。推荐query-string库
跳转:
history.push('/user?a=1&b=2')
history.push({pathname:'/user',search:'?a=11&b=22'})
history.replace({pathname:'/user',search:'?a=111&b=222'})
history.go(-1)
授权路由:自定义路由
Prompt:后置守卫,离开后守卫
import { Prompt } from 'react-router-dom'
<Prompt
when={this.state.isBlocking}
message={location=>{return `未保存,是否去向${location.pathname}`}}
/>
message: 后面可以跟简单的提示语,也可以跟函数,函数是有默认参数的。
when: when的属性值为true时防止跳转;
在对应的index.js
import React from 'react';
import ReactDom from 'react-dom'
import App from "./components/App"
import {BrowserRouter} from 'react-router-dom'
// 渲染dom
ReactDom.render(
<BrowserRouter>
<App />
</BrowserRouter>
,
document.querySelector('#root')
);
在对应的app.js内
import React,{Component} from 'react'
import {Link,Route,NavLink,Redirect,Switch} from 'react-router-dom'
import Home from './home';
import User from './User';
import Product from './Product';
import Detail from './Detail';
import Login from './Login';
import Errorpage from './Errorpage';
import './assets/App.css'
class App extends Component{
render() {
return(
<div>
<h3>react-router</h3>
<NavLink to="/home"activeClassName="app-nav--active"> 首页</NavLink>
<NavLink to="/user"activeStyle={{background:"pink"}}> user</NavLink>
<NavLink to="/product"activeStyle={{background:"pink"}}> 商品</NavLink>
<NavLink to="/login"activeStyle={{background:"pink"}}> login</NavLink>
<Switch>
<Route path='/home' component={Home} ></Route>
<Route path='/user' component={User} ></Route>
<Route path='/product' component={Product}></Route>
<Route path='/login' component={Login}></Route>
<Redirect exact from="/" to="/home" />
<Route component={Errorpage} />
</Switch>
</div>)
}
}
export default App
在project.js
import React,{Component} from 'react'
import {Link,Route} from 'react-router-dom'
import Detail from './Detail';
import querystring from 'query-string'
class Product extends Component{
render(h) {
console.log(this.props)
return (<div>
<h3>商品</h3>
<Link to="/product/1" >商品001</Link>
<Link to={this.props.match.url+'/2'}>商品002</Link>
<Link to="/product/3?aa=1&bb=2">商品003</Link>
<Link to={{pathname:this.props.match.url+'/4',search:'aa=11&bb=22'}}>商品004</Link>
<Link to={{pathname:this.props.match.url+'/5',search:querystring.stringify({aa:111,bb:33})}}>商品005</Link>
<Route path={this.props.match.path+'/:aid'} component={Detail}></Route>
</div>)
}
}
export default Product
在对应的detail
import React,{Component} from 'react'
class Detail extends Component{
render(h) {
return (
<div className="Detail">
<h3>详情</h3>
<a href="javascript:;" onClick={()=>this.props.history.go(-1)}>返回←</a>
</div>)
}
}
export default Detail
在user内,有后置守卫
import React,{Component} from 'react'
import {Prompt} from 'react-router-dom'
class User extends Component{
state={
bl:true
};
render() {
return (<div>
<Prompt
when={this.state.bl}
message={location=>{return `未保存,是否去向${location.pathname}`}}>
<h3>User的内容</h3>
</Prompt>
</div>)
}
}
export default User