이번에는 React에서 라우팅을 사용하는 방법에 대해 자세히 설명하겠습니다. React에서 라우팅을 사용할 때 주의할 점은 무엇인가요? 실제 사례를 살펴보겠습니다.
은 URL을 해당 함수에 매핑하여 구현됩니다. React 라우팅을 사용하려면 먼저 React-router.js를 도입해야 합니다.
참고:
React-router 버전 4.0 이상은 버전 3.0 이하와 매우 다릅니다. 이 튜토리얼에서는 버전 3.0.2를 사용하며 버전 4.0 이상의 튜토리얼은 나중에 업데이트됩니다.
npm을 사용하여 설치하는 경우 기본적으로 최신 버전이 설치됩니다. 설치된 버전이 최신이고 버전 3.0을 사용하는 경우 오류가 보고됩니다.
따라서 npm 설치 시 npm install React-router@3.0.2 --save-dev
버전을 지정해야 합니다. npm install react-router@3.0.2 --save-dev
。
传统的前端基本都是通过页面之间跳转来实现各功能模块的切换,这种做法会导致一个项目下来存在大量的 html 页面,而且每个页面都有一大堆的静态资源文件需要引入,在性能一直被垢病。后来有了随着 ajax 的普及,还有 jQuery 对 ajax 的封装后的便捷使用,开发者会大量的使用 ajax 来加载一个 html 页面到当前页面的某个容器当中来实现无刷新加载,但依然没有解决大量存在 html 页面和每个页面加载大量的静态资源文件而导致性能上的问题。随着移动互联网的普及,移动端对页面加载的性能要求和流量的限制越来越高,所以主流的前端框架都往 SPA 方向靠齐。
SPA,Single Page Application 的缩写,单页面应用,其目的是整个应用程序只有一个 html 页面,结合构建 webpack 的统一打包思想,把所有静态资源文件打包成一个 js 文件,在唯一的一个 html 页面引用,从而真正意义上实现一个 html 文件,一个 js 文件完成一个应用的构想。
SPA 优化了静态加载的性能,但一个应用程序还是有很多的功能模块,功能模块之间的切换,就变成了组件之间的切换,所以到目前为止基本上主流的前端框架都会有路由和组件两个概念,而且实现思想都是一致的。
//es5 var {Router, Route, hashHistory, Link, IndexRoute, browserHistory} = require("react-router"); //es6 import {Router, Route, hashHistory, Link, IndexRoute, browserHistory} from 'react-router'; //es5 和 es6 的使用都是一样的 <Link to="/">Root</Link> <Router> <Route path='/' component={RootComponent}/> </Router> //使用 `<script>` 标签 <script src="../js/ReactRouter.js"></script> <ReactRouter.Link to="/">Root</ReactRouter.Link> <ReactRouter.Router> <ReactRouter.Route path='/' component={RootComponent}/> </ReactRouter.Router>
用于路由之间跳转,功能等同于 a
标签。
属性 to
等同于 a
标签的 href
。
<Link to="/page">page</Link>
,作用等同于 <a href="#/page">page</a>
。
是最外层的路由组件,整个 Application 仅一个。
属性 history
有两个属性值:
hashHistory
路由将通过URL的hash部分(#)切换,推荐使用。
<Router history={hashHistory}>
对应的 URL 形式类似 example.com/#/some/path
browserHistory
这种情况需要对服务器改造。否则用户直接向服务器请求某个子路由,会显示网页找不到的404错误。
<Router history={browserHistory}>
对应的 URL 形式类似 example.com/some/path。
Route
是组件 Router
子组件,可以通过嵌套 route
来实现路由嵌套。
属性 path
:指定路由的匹配规则,这个属性是可以省略的,这样的话,不管路径是否匹配,总是会加载指定组件。
属性 component
:指当 URL 映射到路由的匹配规则时会渲染对应的组件。
<Route path="/" component={RootComponent}/>
当 URL 为 example.com/#/ 时会渲染组件 RootComponent
<Route path="/page1" component={Page1Component}/>
当 URL 为 example.com/#/page1 时会渲染组件 Page1Component
import React from 'react' import ReactDOM from 'react-dom' import {Router, hashHistory, browserHistory} from 'react-router' const html = ( <ul> <li><Link to="/">Root</Link></li> <li><Link to="/page">page</Link></li> </ul> ) class RootComponent extends React.Component{ render(){ return ( <p> <h1>RootComponent</h1> {html} </p> ) } } class PageComponent extends React.Component{ render(){ return ( <p> <h1>PageComponent</h1> {html} </p> ) } } ReactDOM.render( <Router history={hashHistory}> <Route path='/' component={RootComponent}/> <Route path='/page' component={PageComponent}/> </Router>, document.getElementById('app') )
效果预览
路由的参数传递是通过 Route 组件的 path 属性来指定的。
参数值可通过 this.props.params.paramName
来获取。
:paramName
匹配URL的一个部分,直到遇到下一个/、?、#为止。
<Route path="/user/:name">
。
匹配 URL:/#/user/sam,参数 sam 为必须存在。
this.props.params.name
import React from 'react' import ReactDOM from 'react-dom' import {Router, hashHistory, browserHistory} from 'react-router' class UserComponent extends React.Component{ render(){ return ( <p> <h3>UserComponent 单个参数 </h3> <p>路由规则:path='/user/:username'</p> <p>URL 映射:{this.props.location.pathname}</p> <p>username:{this.props.params.username}</p> </p> ) } } ReactDOM.render( <Router history={hashHistory}> <Route path='/user/:username' component={UserComponent}/> </Router>, document.getElementById('app') )🎜경로 구성 요소 및 속성🎜
to
속성은 a
태그의 href
와 동일합니다. 🎜<Link to="/page">page</Link>
, 이 기능은 <a href="#/page와 동일합니다. ">페이지</a>
. 🎜history
속성에는 두 가지 속성 값이 있습니다: 🎜hashHistory
URL의 해시 부분(#)을 통해 경로가 전환되는 것을 권장합니다. 🎜<Router History={hashHistory}>
해당 URL 형식은 example.com/#/some/path🎜와 유사합니다.<Router History={browserHistory}>
해당 URL 형식은 example.com/some/path와 유사합니다. 🎜Route
는 라우터
구성 요소 하위 구성 요소는 route
를 중첩하여 경로 중첩을 실현할 수 있습니다. 🎜path
: 경로의 일치 규칙을 지정합니다. 이 속성은 생략될 수 있습니다. 이 경우 경로 일치 여부에 관계없이 지정된 구성 요소가 항상 로드됩니다. 아니면. 🎜comment
: URL이 경로의 일치 규칙에 매핑될 때 렌더링될 해당 구성 요소를 나타냅니다. 🎜<Route path="/" component={RootComponent}/>
URL이 example.com/#/이면 RootComponent 구성 요소가 렌더링됩니다🎜 <Route path="/page1" component={Page1Component}/>
URL이 example.com/#/page1인 경우 구성요소 Page1Component🎜 li>🎜기본 사용법🎜import React from 'react' import ReactDOM from 'react-dom' import {Router, hashHistory, browserHistory} from 'react-router' class UserComponent extends React.Component{ render(){ return ( <p> <h3>OrderComponent 可选参数 </h3> <p>路由规则:path='/order(/:orderid)'</p> <p>URL 映射:{this.props.location.pathname}</p> <p>orderid:{this.props.params.orderid}</p> </p> ) } } ReactDOM.render( <Router history={hashHistory}> <ReactRouter.Route path='/order(/:orderid)' component={UserComponent}/> </Router>, document.getElementById('app') )🎜효과 미리 보기🎜🎜라우팅 매개변수🎜
this.props.params.paramName
을 통해 얻을 수 있습니다. 🎜:paramName
🎜<경로 경로="/user/:name">
. 🎜this.props.params.name
에는 sam 값이 있습니다. 🎜import React from 'react' import ReactDOM from 'react-dom' import {Router, hashHistory, browserHistory} from 'react-router' class UserComponent extends React.Component{ render(){ return ( <p> <h3>UserComponent 单个参数 </h3> <p>路由规则:path='/user/:username'</p> <p>URL 映射:{this.props.location.pathname}</p> <p>username:{this.props.params.username}</p> </p> ) } } ReactDOM.render( <Router history={hashHistory}> <Route path='/user/:username' component={UserComponent}/> </Router>, document.getElementById('app') )
(:paramName)
表示URL的这个部分是可选的。
<Route path="/order(/:orderid)">
。
匹配 URL:/#/order,this.props.params.orderid
获取的值为 undefined。
匹配 URL:/#/order/001,this.props.params.orderid
获取参数的值为 001。
import React from 'react' import ReactDOM from 'react-dom' import {Router, hashHistory, browserHistory} from 'react-router' class UserComponent extends React.Component{ render(){ return ( <p> <h3>OrderComponent 可选参数 </h3> <p>路由规则:path='/order(/:orderid)'</p> <p>URL 映射:{this.props.location.pathname}</p> <p>orderid:{this.props.params.orderid}</p> </p> ) } } ReactDOM.render( <Router history={hashHistory}> <ReactRouter.Route path='/order(/:orderid)' component={UserComponent}/> </Router>, document.getElementById('app') )
*.*
匹配任意字符,直到模式里面的下一个字符为止。匹配方式是非贪婪模式。
<Route path="/all1/*.*">
。
this.props.params
获取的参数为一个固定的对象: {splat: [*, *]}
。
匹配 URL:/all1/001.jpg,参数为 {splat: ['001', 'jpg']}
。
匹配 URL:/all1/001.html,参数为 {splat: ['001', 'html']}
。
*
匹配任意字符,直到模式里面的下一个字符为止。匹配方式是非贪婪模式。
<Route path="/all2/*">
。
this.props.params
获取的参数为一个固定的对象: {splat: '*'}
。
匹配 URL:/all2/,参数为 {splat: ''}
。
匹配 URL:/all2/a,参数为 {splat: 'a'}
。
匹配 URL:/all2/a/b,参数为 {splat: 'a/b'}
。
**
匹配任意字符,直到下一个/、?、#为止。匹配方式是贪婪模式。
<Route path="/**/*.jpg">
this.props.params
获取的参数为一个固定的对象: {splat: [**, *]}
。
匹配 URL:/all3/a/001.jpg,参数为 {splat: ['a', '001']}
。
匹配 URL:/all3/a/b/001.jpg,参数为 {splat: ['a/b', '001']}
。
效果预览
当访问一个嵌套路由时,指定默认显示的组件
import React from 'react' export default class AppComponent extends React.Component{ render(){ return <p>{this.props.children}</p> } }
import React, {Component} from 'react' export default class LoginComponent extends Component{ login(){} render(){ return <h1>Login</h1> } }
import React, {Component} from 'react' export default class HomeComponent extends Component{ login(){} render(){ return <h1>Home</h1> } }
import React from 'react' import {Route, IndexRoute} from 'react-router' import AppComponent from '../components/app/app' import HomeComponent from '../components/home/home' import LoginComponent from '../components/login/login' const routes = ( <Route path="/" component={AppComponent}> <IndexRoute component={HomeComponent} /> <Route path="login" component={LoginComponent} /> <Route path="home" component={HomeComponent} /> </Route> ) export default routes;
如果没有加IndexRoute
,则在访问 http://localhost/#/
时页面是空白的
访问 http://localhost/#/login
才会显示内容
加上 IndexRoute
,在访问http://localhost/#/
时会默认渲染HomeComponent
可利用组件Router
的属性routes
来实现组件模块化
import React from 'react' import ReactDOM from 'react-dom' import {Route, Router, IndexRoute, hashHistory} from 'react-router' import AppComponent from '../components/app/app' import HomeComponent from '../components/home/home' import LoginComponent from '../components/login/login' const routes = ( <Route path="/" component={AppComponent}> <IndexRoute component={HomeComponent} /> <Route path="login" component={LoginComponent} /> <Route path="home" component={HomeComponent} /> </Route> ) ReactDOM.render( <Router history={hashHistory} routes={routes} />, document.getElementById('app') )
普通跳转 this.props.router.push('/home/cnode')
带参数跳转this.props.router.push({pathname: '/home/cnode', query: {name: 'tom'}})
每个路由都有enter
和leave
两个钩子函数,分别代表用户进入时和离开时触发。
进入路由/home
前会先触发onEnter
方法,如果已登录,则直接next()
正常进入目标路由,否则就先修改目标路径replace({ pathname: 'login' })
,再next()
跳转。
let isLogin = (nextState, replace, next) => { if(window.localStorage.getItem('auth') == 'admin'){ next() } else { replace({ pathname: 'login' }) next(); } } const routes = ( <Route path="/" component={AppComponent}> <Route path="login" component={LoginComponent} /> <Route path="home" component={HomeComponent} onEnter={isLogin}/> </Route> )
对应的setRouteLeaveHook
方法,如果return true
则正常离开,否则则还是停留在原路由
import React from 'react' import {Link} from 'react-router' export default class Component1 extends React.Component{ componentDidMount(){ this.props.router.setRouteLeaveHook( this.props.route, this.routerWillLeave ) } routerWillLeave(){ return '确认要离开?' } render(){ return ( <p> <Link to="/login">Login</Ling> </p> ) } }
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
위 내용은 React의 라우팅 사용법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!