React 路由的使用
安装并引入使用
npm i react-router-dom
HashRouter
①基于hash模式:页面跳转原理是使用了location.hash、location.replace;和vue router的hash模式实现一致
②比较丑:在域名后,先拼接/#,再拼接路径;也就是利用锚点,实现路由的跳转;如:http://www.abc.com/#/xx
BrowserRouter
①基于history模式:页面跳转原理是使用了HTML5为浏览器全局的history对象新增了两个API,包括 history.pushState、history.replaceState;和vue router的history模式实现一致
②更加优雅: 直接拼接路径;如:http://www.abc.com/xx
③后端需做请求处理: 切换路由后,请求接口路径会发生变化,后端需要配合,做处理
BrowserRouter在本地build打包之后访问index.html打开出现白屏的情况, 使用HashRouter则不会出现这种情况,所以本地静态页面的话选择HashRouter好一些
//引入react核心库
import React from 'react'
//引入ReactDOM
import ReactDOM from 'react-dom'
//
import {BrowserRouter} from 'react-router-dom'
//引入App
import App from './App'
ReactDOM.render(
<BrowserRouter>
<App/>
</BrowserRouter>,
document.getElementById('root')
)
注册路由
<Switch>
<Route path="/about" component={About}/>
<Route path="/home" component={Home}/> //加了switch 匹配到了第一个/home之后就不会继续往下匹配了 如果不加switch则所有匹配结果都会被渲染 因此加上switch可以提高匹配效率
<Route path="/home" component={Test}/>
<Redirect to="/404"/> //路由匹配失败 重定向到404页面
</Switch>
NavLink的使用
<NavLink to="/about">About</NavLink>
<NavLink to="/home">Home</NavLink>
<NavLink to="/home/a/b/c">Home</NavLink> //多级路由/嵌套路由即可以在home页面里注册a页面 -> a页面注册b -> b页面注册c
使用路由进行页面间的传参
① params传参
刷新页面参数不消失,参数会在地址栏显示
{/* 声明接收params参数 传一个id和一个title参数 */}
<Route path="/home/message/detail/:id/:title" component={Detail}/>
{/*使用Link传递参数*/}
<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>
{/* 编程式传参 */}
this.props.history.replace(`/home/message/detail/${id}/${title}`)
this.props.history.push(`/home/message/detail/${id}/${title}`)
//Detail组件里接收params参数
const {id,title} = this.props.match.params
② Search传参
刷新页面参数不消失,参数会在地址栏显示
{/* search参数无需声明接收,正常注册路由即可 */}
<Route path="/home/message/detail" component={Detail}/>
{/* 向路由组件传递search参数 */}
<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>
{/* 编程式传参 */}
this.props.history.replace(`/home/message/detail?id=${id}&title=${title}`)
this.props.history.push(`/home/message/detail?id=${id}&title=${title}`)
//Detail组件里接收Search的参数
//要依赖个解析参数的库
import qs from 'querystring'
const {id,title} = qs.parse(search.slice(1))
③ query传参
刷新页面参数消失,参数不会在地址栏显示
{/* query参数无需声明接收,正常注册路由即可 */}
<Route path="/home/message/detail" component={Detail}/>
{/* 向路由组件传递query参数 */}
<Link to={{pathname:'/home/message/detail',query: {id: msgObj.id,title: msgObj.title}>{msgObj.title}</Link>
{/* 编程式传参 */}
this.props.history.replace({pathname:'/home/message/detail',query: {id: msgObj.id,title: msgObj.title})
this.props.history.push({pathname:'/home/message/detail',query: {id: msgObj.id,title: msgObj.title})
//Detail组件里接收query的参数
const {id,title} = this.props.location.query
④ 通过state携带参数
1、BrowserRouter(history)模式下,刷新页面参数不消失,参数不会在地址栏显示,因为state保存在history对象中
2、HashRouter(hash)模式下,刷新页面参数消失!!!参数不会在地址栏显示
{/* state参数无需声明接收,正常注册路由即可 */}
<Route path="/home/message/detail" component={Detail}/>
{/* 向路由组件传递state参数 */}
<Link to={{pathname:'/home/message/detail',state:{id:msgObj.id,title:msgObj.title}}}>{msgObj.title}</Link>
{/* 编程式传参 */}
this.props.history.replace(`/home/message/detail`,{id,title})
this.props.history.push(`/home/message/detail`,{id,title})
//Detail组件里接收state参数
const {id,title} = this.props.location.state || {}
replace 是把当前页面干掉去往一个新页面 push是当前页面还存在,压入一个新的页面进栈
**在不同的场景,可以使用不同的传参方式(适合的才是最好的): **
state传参:BrowserRouter(history)模式下,刷新页面不消失;而HashRouter(hash)模式下,刷新页面会消失,但都不会暴露在url中params传参(动态路由): 可读性高,便于维护,当另一个页面一定需要某数据时,推荐使用query传参: 虽然不会暴露在url中,但刷新页面会消失search传参: 会暴露在url中,刷新页面不会消失,但取数据时需处理
withRouter可以加工一般组件,让一般组件具备路由组件所特有的API
withRouter的返回值是一个新组件
//组件里定义几个按钮 按钮点击调用以下方法就可以操作路由了
this.props.history.goForward()//前进一步
this.props.history.goBack() //后退一步
this.props.history.go(-2) //后退2步 数值为正则前进 为负则后退
// 以上都基于浏览器的history进行的操作 如果history页面数量小于等于一个页面则无效
//注意⚠️ 组件最后还得声明一下 withRouter
export default withRouter(XXX) //xxx为组件名
参考资料
本文来自博客园,作者:CoderWGB,转载请注明原文链接:https://www.cnblogs.com/wgb1234/articles/16794386.html

浙公网安备 33010602011771号