内容简介: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… 处获得。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
The Mechanics of Web Handling
David R. Roisum
This unique book covers many aspects of web handling for manufacturing, converting, and printing. The book is applicable to any web including paper, film, foil, nonwovens, and textiles. The Mech......一起来看看 《The Mechanics of Web Handling》 这本书的介绍吧!