多应用+插件架构,代码干净,二开方便,首家独创一键云编译技术,文档视频完善,免费商用码云13.8K 广告
http://uprogrammer.cn/react-router-cn/docs/guides/basics/Histories.html https://www.jianshu.com/p/336770af0047 # react-router >react-router react-router-dom react-router-native * 路由组件,比如 `<BrowserRouter>` 和 `<HashRouter>` * 路由匹配组件,比如 `<Route>` 和 `<Switch>` * 导航组件,比如 `<Link>`, `<NavLink>`, 和 `<Redirect>` ## 路由组件 * `BrowserRouter`:history路由, `HTML5` 提供的 history API ( pushState , replaceState 和 popstate 事件) 来保持 UI 和 url 的同步。打包后打开访问不了页面,需要通过配置nginx解决或者后台配置代理。 * `HashRouter`:哈希路由,在路径前加入#号成为一个哈希值,不会因为刷新而找不到对应路径,但是链接上面会有`#/`。 ```js import { BrowserRouter } from 'react-router-dom'; <BrowserRouter basename="/calendar" ><App /></BrowserRouter> ``` ## 匹配组件 在`<Switch>`里面包裹多个`<Route>`,然后它会逐步去比对每个`<Route>`的path属性 和浏览器当前location的pathname是否一致,如果一致则返回内容,否则返回null。 ```js <Switch> <Route exact path='/' component={Home} /> {/* 如果当前的URL是`/about`,即 location = { pathname: '/about' } ,那么About组件就应该被渲染,其余的Route就会被忽略 */ <Route path='/about' component={About} /> <Route path="/detail" render={(props)=><Home {...props}/>}></Route> {/* 当上面的组件都没有匹配到的时候, 404页面就会被render */} <Route render={() => <div> 404页面 </div>} /> </Switch> ``` `<Route path={xxx}>` 只会匹配 `URL`的开头,而不是整个 URL。简单的来说就是它不是精确匹配 ,例如`<Route path ='/'>` 和`<Route path ='/about'>` 它永远都只能匹配到`<Route path ='/'>`,他们开头都有'/' 。解决方案: * 方法一:将此`<Route path='/'>`放在`<Switch>`的最后一个位置 * 方法二: 添加exact 实现精确匹配:`<Route exact='/'>` **component方式和render方式的区别** * 用component渲染页面的时候,会默认给渲染的组件传递三个值:history、match、location。render需要手动给函数加参数(也可以通过withRouter来搞定) * render 可以渲染组件,也可以渲染标签 * render 渲染的时候,可以进行传值。因为是标签,可以直接属性传值,props取值 * 一般情况下,通过render 的形式进行路由嵌套 * render 更自由,可以进行更多的业务逻辑 - withRouter高阶组件 ~~~jsx import { withRouter } from 'react-router-dom' {{/* 导出时用 withRouter 对创建的组件进行加工,则组件内即可访问history、match和location */}} export default withRouter(MyComponent); ~~~ - **路由嵌套** 路由如果要嵌套的话,父级路由必须要用render方式来渲染,在函数内对子级路由进行操作。 ~~~jsx <Route path="/father" render={()=>( <Fragment> <Route component={Father}/> <Switch> <Redirect from="/father" to="/father/childone" exact /> <Route path="/father/childone" component={ChildOne}/> <Route path="/father/childtwo" component={ChildTwo}/> </Switch> </Fragment> )}></Route> ~~~ ## 导航组件 `<Link>`,`<NavLink>`, 和`<Redirect>` ```js // 有onclick那就执行onclick,,click的时候阻止a标签默认事件 <Link to='/'>Home</Link> // 渲染为a标签 <a href='/'>Home</a> // NavLink组件在活跃项身上会有一个类名为`active`的标识 <NavLink to='/about' activeClassName='active'>About</NavLink> ``` - **路由重定向** ~~~jsx import { Redirect } from 'react-router-dom' // 如果在 "/" 路径,重定向到 "/home" 路径 <Redirect from="/" to="/home" /> ~~~ ## **路由跳转和传值** 用`this.props.history.xxx`的方式,必须要有history参数,用component方式渲染的页面默认有,如果用render渲染,需要手动传参 ~~~jsx this.props.history.push("/home"); // 跳转到 this.props.history.goBack(); // 返回 this.props.history.goForward this.props.history.go this.props.history.replace ~~~ ## 路由传值 - **动态路由传值** ~~~jsx // /:属性 <Route to="/detail/:id" component={Detail}></Route> // link 使用 /:值 传递下去 <Link to="/detail/"+item.id>{item.name}</Link> // 页面通过`this.props.match.params`接收 <h2>接收到商品id为:{this.props.match.params.id}</h2> ~~~ - **query传值** ~~~jsx <Link to="/detail?id="+item.id>{item.name}</Link> // 页面通过this.props.location.search接收 <h2>接收到商品id为:{url.parse(this.props.location.search).query}</h2> ~~~ - **内存传值** 把传递的值存在了对象里,刷新页面后值会消失,用于登录返回页面路径的存储 ~~~jsx // query的名字是自己取的 <Link to={{ path:"/detail", query:{ id:item.id } }}> {item.name} </Link> // this.props.location 接收 <h2>接收到商品id为:{this.props.location.query.id}</h2> ~~~ ## 路由懒加载—react-loadable ~~~jsx // 1. 安装 cnpm i react-loadable -S // 2. 引入 import loadable from 'react-loadable' // 3. 配置 // 不用路由懒加载的时候,组件是默认的引入方式 import Home from './components/home' // 用路由懒加载引入组件 const Home = loadable({ loader: ()=>import("./components/home"), loading: Loading {/* Loading是自己的Loading组件 */} }) ~~~