内容简介:Create byRecently revised inHello 小伙伴们,如果觉得本文还不错,记得给个star, 小伙伴们的star是我持续更新的动力!
Create by jsliang on 2019-04-26 13:13:18
Recently revised in 2019-04-29 15:25:01
Hello 小伙伴们,如果觉得本文还不错,记得给个star, 小伙伴们的star是我持续更新的动力! GitHub 地址
一 目录
不折腾的前端,和咸鱼有什么区别
目录 |
---|
5.1 BrowserRouter 语法 |
5.2 BrowserRouter - basename |
5.3 BrowserRouter - getUserConfirmation |
5.4 BrowserRouter - forceRefresh |
5.5 BrowserRouter - keyLength |
6.1 HashRouter - basename |
6.2 HashRouter - getUserConfirmation |
6.3 HashRouter - hashType |
8.1 NavLink - activeClassName |
8.2 NavLink - activeStyle |
8.4 NavLink - isActive |
9.1 MemoryRouter - initialEntries |
9.2 MemoryRouter - initialIndex |
9.3 MemoryRouter - getUserConfirmation |
9.4 MemoryRouter - keyLength |
10.4 Redirect - exact |
11.1 Route - component |
11.3 Route - children |
11.6 Route - location |
11.7 Route - sensitive |
十四 篇外二:Code Splitting |
十五 篇外三:Scroll To Top |
15.1 跳转页面后滚动到顶部 |
二 前言
前端路由,是指改变 URL 路径的形式,从而切换到不同的页面,例如:
localhost:3000/home localhost:3000/user
通过切换不同的 URL,显示不同的页面,从而有了 路由 的概念。
这篇文章我们讲解在 React 中如何通过 React Router 这个插件,灵活使用路由。
jsliang瞎吹的,最好自己百度 前端路由 是啥。
- 参考资料:
- React Router 官方文档
- React Router 中文文档
- React Router 中文文档(旧)
- React Router DOM 中文文档(一) - 简书
- React Router DOM 中文文档(二) - 简书
- 篇外话题:
网上有很多 React Router 文章了,例如:
为何 jsliang 要多次一举?
- 你记录你的,我记录我的,互相不妨碍。
- 看这些跟看官网没啥两样,所以我需要亲自动手过一遍官网。
- 记录我看官网的内容,顺带记录我应用上去的实例,方便我下次回顾。
三 初试
当前版本: "react-router-dom": "^5.0.0"
首先,在 Create React App 中,我们引用 React Router:
-
npm i react-router-dom -S
然后,在 src 目录下新建 pages 用来存放页面,并修改 App.js:
案例:App.js
import React, { Fragment } from 'react'; import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom'; import ScrollToTop from './components/ScrollToTop'; import Header from './components/Header'; import TimeLine from './pages/TimeLine'; import NotFound from './pages/404'; function App() { return ( <Fragment> <BrowserRouter> <Header /> <ScrollToTop> <Switch> <Redirect from="/" to="/timeline" exact /> <Route path="/timeline" component={TimeLine}></Route> <Route component={NotFound}></Route> </Switch> </ScrollToTop> </BrowserRouter> </Fragment> ); } export default App; 复制代码
最后,通过在 App.js 中如此定义,即可定义对应的组件,并渲染对应页面和进行跳转。
四 简介
下面我们拿一些常用的进行介绍:
import { BrowserRouter, HashRouter, Redirect, Route, NavLink, Link, MemoryRouter, Switch, withRouter } from "react-router-dom"; 复制代码
-
<BrowserRouter>
:路由组件包裹层。<Route>
和<Link>
的包裹层。 -
<HashRouter>
:路由组件包裹层。相对于<BrowserRouter>
来说,更适合静态文件的服务器。 -
<Redirect>
:路由重定向。渲染<Redirect>
将使导航到一个新的地址。 -
<Route>
:路由。定义一个路由页面,用来匹配对应的组件(Component)和路由路径。 -
<NavLink>
:活跃链接。当 URL 中的路径等于该路由定义的路径时,该标签可以呈现它定义的activeClassName
。 -
<Link>
:链接。用来跳转到<Route>
对应的路由(Component) 中。 -
<MemoryRouter>
:暂未使用。<Router>
能在内存中保存URL
的历史记录。很适合在测试环境和非浏览器环境中使用,例如 React Native。 -
<Switch>
:路由分组。渲染与该地址匹配的第一个子节点<Route>
或者<Redirect>
。可以利用<Switch>
做分组。 -
<withRouter>
:路由组合。通过<withRouter>
高阶组件访问history
对象的属性和最近的<Route>
的match
。或者利用它来结合 Redux。
五 BrowserRouter
<BrowserRouter>
会为你创建一个专门的 history 对象,用来记录你的路由,从而能够返回上一页或者跳转到指定的路由页面。
区别于 <HashRouter>
,有响应请求的服务器时使用 <BrowserRouter>
,使用的是静态文件的服务器,则用 <HashRouter>
。
简单案例:
<BrowserRouter> <Header /> <Route path="/" exact component={TimeLine}></Route> <Route path="/timeline" component={TimeLine}></Route> </BrowserRouter> 复制代码
5.1 BrowserRouter 语法
import { BrowserRouter } from 'react-router-dom' <BrowserRouter basename={optionalString} forceRefresh={optionalBool} getUserConfirmation={optionalFunc} keyLength={optionalNumber} > <App/> </BrowserRouter> 复制代码
5.2 BrowserRouter - basename
- 规则:
basename: string
为里面的子目录提供基础路径名,例如:
<BrowserRouter basename="/calendar"> <Link to="/today"/> {/* 渲染为 <a href="/calendar/today"> */} </BrowserRouter> 复制代码
5.3 BrowserRouter - getUserConfirmation
- 规则:
getUserConfirmation: function
用于确认导航的功能。
// 默认使用 window.confirm。 const getConfirmation = (message, callback) => { const allowTransition = window.confirm(message) callback(allowTransition) } <BrowserRouter getUserConfirmation={getConfirmation}/> 复制代码
5.4 BrowserRouter - forceRefresh
- 规则:
forceRefresh: bool
如果为 true,则路由器将在页面导航中使用整页刷新
const supportsHistory = 'pushState' in window.history <BrowserRouter forceRefresh={!supportsHistory}/> 复制代码
5.5 BrowserRouter - keyLength
- 规则:
keyLength: number
设置它里面路由的 location.key
的长度。默认为 6。
key 的作用:点击同一个链接时,每次该路由下的 location.key都会改变,可以通过 key 的变化来刷新页面。
<BrowserRouter keyLength={12}/> 复制代码
六 HashRouter
使用 URL
的 hash
部分(即 window.location.hash
)的 <Router>
使 UI
与 URL
保持同步。
重要提示 :Hash
历史记录不支持 location.key
或 location.state
。
import { HashRouter } from 'react-router-dom' <HashRouter> <App/> </HashRouter> 复制代码
6.1 HashRouter - basename
- 规则:
basename: string
所有位置的基本 URL
,格式正确的基本名应该有一个前导斜线,但结尾不能有斜线。
<HashRouter basename="/calendar"/> <Link to="/today"/> {/* 渲染为 <a href="/calendar/today"> */} 复制代码
6.2 HashRouter - getUserConfirmation
- 规则:
getUserConfirmation: func
用于确认导航的功能。默认使用 window.confirm。
// this is the default behavior const getConfirmation = (message, callback) => { const allowTransition = window.confirm(message) callback(allowTransition) } <HashRouter getUserConfirmation={getConfirmation}/> 复制代码
6.3 HashRouter - hashType
- 规则:
hashType: string
用于 window.location.hash
的编码类型。可用的值是:
-
slash
- 创建#/
和的#/sunshine/lollipops
-
noslash
- 创建#
和的#sunshine/lollipops
-
hashbang
- 创建ajax crawlable
,如#!/
和#!/sunshine/lollipops
默认为 slash
。
七 Link
在应用程序周围提供声明式的,可访问的导航。
7.1 Link - to
- 规则 1:
to: string
链接位置的字符串表示,通过连接位置的路径名,搜索和 hash
属性创建。
<Link to='/courses?sort=name'>字符串形式跳转</Link> 复制代码
- 规则 2:
to: object
一个可以具有以下任何属性的对象:
-
pathname
: 表示要链接到的路径的字符串。 -
search
: 表示查询参数的字符串形式。 -
hash
: 放入网址的hash
,例如#a-hash
。 -
state
: 状态持续到location
。
<Link to={{ pathname: '/courses', // 基础路径 search: '?sort=name', // 匹配字段 hash: '#the-hash', // 对应内链 state: { fromDashboard: true } // 未知 }}> 对象形式跳转 </Link> 复制代码
7.2 Link - replace
- 规则:
replace: bool
如果为 true
,则单击链接将替换历史堆栈中的当前入口,而不是添加新入口。
<Link to="/courses" replace>替换当前 hash 路径</Link> 复制代码
7.3 Link - other
还可以传递想要放在 <a>
上的属性,例如标题, ID
、 className
等。
<Link to="/test" id="myTest">测试 1</Link> 复制代码
八 NavLink
一个特殊版本的 Link,当它与当前 URL 匹配时,为其渲染元素添加样式属性。
- 高亮显示首页:
<NavLink to="/timeline" activeClassName="active">首页</NavLink>
8.1 NavLink - activeClassName
- 规则:
activeClassName: string
要给出的元素的类处于活动状态时。默认的给定类是 active
。它将与 className
属性一起使用。
<NavLink to="/faq" activeClassName="selected" >FAQs</NavLink> 复制代码
8.2 NavLink - activeStyle
- 规则:
activeStyle: object
当元素处于 active 时应用于元素的样式。
<NavLink to="/faq" activeStyle={{ fontWeight: 'bold', color: 'red' }} >FAQs</NavLink> 复制代码
8.3 NavLink - exact
- 规则:
exact: bool
如果为 true
,则仅在位置完全匹配时才应用 active
的类/样式。
<NavLink exact to="/profile" >Profile</NavLink> 复制代码
8.4 NavLink - isActive
- 规则:
isActive: function
一个为了确定链接是否处于活动状态而添加额外逻辑的函数,如果你想做的不仅仅是验证链接的路径名与当前 URL 的 pathname 是否匹配,那么应该使用它
// 如果链接不仅仅匹配 events/123,而是所有奇数链接都匹配 const oddEvent = (match, location) => { if (!match) { return false } const eventID = parseInt(match.params.eventID) return !isNaN(eventID) && eventID % 2 === 1 } <NavLink to="/events/123" isActive={oddEvent} >Event 123</NavLink> 复制代码
九 MemoryRouter
<Router>
能在内存中保存 URL
的历史记录(并不会对地址栏进行读写)。很适合在测试环境和非浏览器环境中使用,例如 React Native。
<MemoryRouter> <App/> </MemoryRouter> 复制代码
9.1 MemoryRouter - initialEntries
- 规则:
initialEntries: array
history
栈中的一个 location
数组。这些可能是具有 { pathname, search, hash, state }
或简单的 URL
字符串的完整地址对象。
<MemoryRouter initialEntries={[ '/one', '/two', { pathname: '/three' } ]} initialIndex={1} > <App/> </MemoryRouter> 复制代码
9.2 MemoryRouter - initialIndex
- 规则:
initialIndex: number
在 initialEntries
数组中的初始化地址索引。
9.3 MemoryRouter - getUserConfirmation
- 规则:
getUserConfirmation: function
用于确认导航的函数。在使用 <MemoryRouter>
时,直接使用 <Prompt>
,你必须使用这个选项。
9.4 MemoryRouter - keyLength
- 规则:
keyLength: number
location.key
的长度。默认为 6。
十 Redirect
渲染 <Redirect>
将使导航到一个新的地址。这个新的地址会覆盖 history
栈中的当前地址,类似服务器端(HTTP 3xx)的重定向。
我们可以设置某个路由重定向到另一个路由,例如下面即对 /
完全匹配重定向到 /timeline
页面。
<Redirect from="/" to="/timeline" exact /> 复制代码
10.1 Redirect - from
- 规则:
from: string
重定向 from
的路径名。可以是任何 path-to-regexp
能够识别的有效的 URL
路径。
所有匹配的 URL
参数都提供给 to
中的模式。
必须包含在 to
中使用的所有参数。
to
未使用的其他参数将被忽略。
<Switch> <Redirect from="/old-path" to="/new-path" /> <Route path="/new-path" component={Place} /> </Switch> 复制代码
10.2 Redirect - to
- 规则:
to: string
重定向到的 URL
,可以是任何 path-to-regexp
能够理解有效 URL
路径。
在 to
中使用的 URL
参数必须由 from
覆盖。
<Redirect to="/somewhere/else" /> 复制代码
- 规则:
to: object
重定向到的 location
, pathname
可以是任何 path-to-regexp
能够理解的有效的 URL
路径。
<Redirect to={{ pathname: "/login", search: "?utm=your+face", state: { referrer: currentLocation } }} /> 复制代码
10.3 Redirect - push
- 规则:
push: bool
当 true
时,重定向会将新地址推入 history
中,而不是替换当前地址。
<Redirect push to="/somewhere/else" /> 复制代码
10.4 Redirect - exact
- 规则:
exact: bool
完全匹配 from
。
十一 Route
只要应用程序位置与 Route 的路径匹配,组件就会被渲染。
11.1 Route - component
只有当位置匹配时才会渲染的 React 组件。
<Route path="/user/:username" component={User}/> const User = ({ match }) => { return <h1>Hello {match.params.username}!</h1> } 复制代码
11.2 Route - render
- 规则:
render: function
这允许方便的内联渲染和包裹,而不是上面那种不想要的重新安装的解释
可以传递一个在位置匹配时调用的函数,而不是使用属性为您创建新的 React element component
,该 render
属性接收所有相同的 route props
的 component
渲染属性。
// 行内编写 <Route path="/home" render={() => <div>Home</div>}/> // 包裹分开写 const FadingRoute = ({ component: Component, ...rest }) => ( <Route {...rest} render={props => ( <FadeIn> <Component {...props}/> </FadeIn> )}/> ) <FadingRoute path="/cool" component={Something}/> 复制代码
11.3 Route - children
- 规则:
children: function
有时你需要渲染路径是否匹配位置。在这些情况下,您可以使用函数 children
属性,它的工作原理与渲染完全一样,不同之处在于它是否存在匹配。
children
渲染道具接收所有相同的 route props
作为 component
和 render
方法,如果 Route
与 URL
不匹配, match
则为 null
,这允许你动态调整你的 UI
界面,基于路线是否匹配,如果路线匹配我们则添加一个 active
类。
<ul> <ListItemLink to="/somewhere"/> <ListItemLink to="/somewhere-else"/> </ul> const ListItemLink = ({ to, ...rest }) => ( <Route path={to} children={({ match }) => ( <li className={match ? 'active' : ''}> <Link to={to} {...rest}/> </li> )}/> ) 复制代码
11.4 Route - path
- 规则:
path: string
任何 path-to-regexp
可以解析的有效的 URL
路径
<Route path="/users/:id" component={User}/> 复制代码
11.5 Route - exact
- 规则:
exact: bool
如果为 true
,则只有在路径完全匹配 location.pathname
时才匹配。
path | location.pathname | exact | matches? |
---|---|---|---|
/one | /one/two | true | no |
/one | /one/two | false | yes |
<Route exact path="/one" component={About}/> 复制代码
jsliang个人经验:
- 加了
exact
属性后,会完全匹配路径;如果没有加,则二级路径也会匹配当前路径(例如/timeline/book
)。
<BrowserRouter> <Route path="/" exact component={TimeLine}></Route> <Route path="/timeline" component={TimeLine}></Route> </BrowserRouter> 复制代码
- 我们可以动态设置
extra
的值,从而判断是否需要加载某个组件。
const Home = () => <div>Home</div>; const App = () => { const someVariable = true; return ( <Switch> {/* these are good */} <Route exact path="/" component={Home} /> <Route path="/about" render={props => <About {...props} extra={someVariable} />} /> {/* do not do this */} <Route path="/contact" component={props => <Contact {...props} extra={someVariable} />} /> </Switch> ); }; 复制代码
11.6 Route - location
- 规则:
location: object
一个 <Route>
元素尝试其匹配 path
到当前的历史位置(通常是当前浏览器 URL)。但是,也可以通过location 一个不同 pathname
的匹配。
11.7 Route - sensitive
- 规则:
sensitive: bool
如果路径区分大小写,则为 true
,则匹配。
path | location.pathname | sensitive | matches? |
---|---|---|---|
/one | /one | true | yes |
/One | /one | true | no |
/One | /one | false | yes |
<Route sensitive path="/one" component={About}/> 复制代码
十二 Switch
渲染与该地址匹配的第一个子节点 <Route>
或者 <Redirect>
。
可以利用 <Switch>
做分组,即当有匹配时,匹配对应 path
对应的组件;如果没有匹配,则匹配 NotFound
页面。
<BrowserRouter> <Header /> <Switch> <Route path="/" exact component={TimeLine}></Route> <Route path="/timeline" component={TimeLine}></Route> <Route component={NotFound}></Route> </Switch> </BrowserRouter> 复制代码
十三 篇外一:history
history
是一个包,在你安装 React Router 的时候,会作为它依赖包安装到项目中,所以你可以直接使用 history
中的属性和方法:
-
length
- (number
类型)history
堆栈的条目数 -
action
- (string
类型) 当前的操作(push
,replace
,pop
) -
location
- (object
类型) 当前的位置。location
会具有以下属性:-
pathname
- (string
类型) URL 路径 -
search
- (string
类型) URL 中的查询字符串 -
hash
- (string
类型) URL 的哈希片段 -
state
- (object
类型) 提供给例如使用push(path, state)
操作将
-
-
location
放入堆栈时的特定location
状态。只在浏览器和内存历史中可用 -
push(path, [state])
- (function
类型) 在history
堆栈添加一个新条目 -
replace(path, [state])
- (function
类型) 替换在history
堆栈中的当前条目 -
go(n)
- (function
类型) 将history
堆栈中的指针调整n
-
goBack()
- (function
类型) 等同于go(-1)
-
goForward()
- (function
类型) 等同于go(1)
-
block(prompt)
- (function
类型) 阻止跳转
十四 篇外二:Code Splitting
随着应用的增长,代码包会随着生长。
到最后你会发现,你打包后的 js 文件大地太多离谱。
所以,我们需要通过代码分割,依据不同的路由,加载不同的 js 文件。
npm i react-loadable -S
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom'; import Loadable from 'react-loadable'; const Loading = () => <div>Loading...</div>; const Home = Loadable({ loader: () => import('./routes/Home'), loading: Loading, }); const About = Loadable({ loader: () => import('./routes/About'), loading: Loading, }); const App = () => ( <Router> <Switch> <Route exact path="/" component={Home}/> <Route path="/about" component={About}/> </Switch> </Router> ); 复制代码
- 打包项目:
npm run build
十五 篇外三:Scroll To Top
15.1 跳转页面后滚动到顶部
- 首先 ,在全局 components 文件中定义 ScrollToTop 文件夹,其中 index.js 内容为:
src/components/ScrollToTop/index.js
import { Component } from 'react'; import { withRouter } from 'react-router-dom'; class ScrollToTop extends Component { componentDidUpdate(prevProps) { if (this.props.location !== prevProps.location) { window.scrollTo(0, 0) } } render() { return this.props.children } } export default withRouter(ScrollToTop); 复制代码
- 然后 ,在 App.js 或者其他页面中使用 ScrollToTop 功能:
src/App.js
import React, { Fragment } from 'react'; import { BrowserRouter, Route, Switch, Redirect } from 'react-router-dom'; import ScrollToTop from './components/ScrollToTop'; import Header from './components/Header'; import TimeLine from './pages/TimeLine'; import NotFound from './pages/404'; function App() { return ( <Fragment> <BrowserRouter> <Header /> <ScrollToTop> <Switch> <Redirect from="/" to="/timeline" exact /> <Route path="/timeline" component={TimeLine}></Route> <Route component={NotFound}></Route> </Switch> </ScrollToTop> </BrowserRouter> </Fragment> ); } export default App; 复制代码
- 最后 ,我们切换路由的时候,页面就会滚动到顶部。
15.2 页面滚动到顶部
暂未实现
十六 篇外四:Redux
在项目中,我们更希望 React Router 和 React Redux 合并起来,这时候可以:
// before export default connect(mapStateToProps)(Something) // after import { withRouter } from 'react-router-dom' export default withRouter(connect(mapStateToProps)(Something)) 复制代码
- 参考文献:Redux Integration
十七 总结
如果你纯粹过文档(官方文档, jsliang 的文档),你会觉得毫无趣味、了无生趣、乏味、沉闷……
所以, jsliang 的学法是:开启了一个项目,边翻阅文档,边应用到项目中,并进行 Mark 标记,以便下次使用。
如此,该文档虽然完结了,但是仍未完结!完结的是我过完了官方文档,未完结的是 React Router 在我项目中可能有其他应用,需要我一一添加进来。
jsliang广告推送:
也许小伙伴想了解下云服务器
或者小伙伴想买一台云服务器
或者小伙伴需要续费云服务器
欢迎点击 云服务器推广 查看!
jsliang 的文档库 由 梁峻荣 采用 知识共享 署名-非商业性使用-相同方式共享 4.0 国际 许可协议 进行许可。
基于 github.com/LiangJunron… 上的作品创作。
本许可协议授权之外的使用权限可以从 creativecommons.org/licenses/by… 处获得。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Ext JS学习指南
(美)布莱兹、(美)拉姆齐、(美)弗雷德里克 / 孔纯、肖景海、张祖良 / 人民邮电出版社 / 2009-10 / 39.00元
《Ext JS学习指南》系统化地介绍了Ext JS的基础知识,从框架的下载安装到各种常用小部件的实例介绍,从如何自定义小部件到Ext JS代码复用和扩展机制,《Ext JS学习指南》覆盖了Ext JS知识的所有主要方面。作为Web 2.0时代企业应用的一把开发利器,Ext JS为企业应用开发的表现层实现提供了优秀的解决方案。 如果你掌握了HTML,并且了解一般的CSS和JavaScript的......一起来看看 《Ext JS学习指南》 这本书的介绍吧!