React 中的路由

1,737 阅读4分钟

react中的路由管理 REACT-ROUTER-DOM(第四代版本开始) - HASH路由(地址丑)

react-router-dom实现SPA单页面应用

yarn add react-router-dom

REACT-ROUTER提供了两种路由方式:

1.Brower-router(基于H5中的history-api完成)(需要服务器对404页面做处理:如果请求的页面不存在,让其渲染首页的内容)
    - http://www.xxx.com/user
    - http://www.xxx.com/user/singin

 2.Hash-router(基于HASH值处理的)
    - http://www.xxx.com/#/user
    - http://www.xxx.com/#/user/singin

如果项目是单纯静态页面展示(数据绑定是由客户端完成的),一般使用hash-router完成;如果当前的项目有些内容是需要后台完成,我们尽量使用brower-router,因为hash值不太容易和服务器端产生关联;

基础使用

import React, { Component } from 'react';
import { HashRouter, BrowserRouter, Switch, Route, Redirect } from 'react-router-dom';
import Custom from './Custom';
import System from './System';
import Error from './Error';

class App extends Component {
	render() {
		return <>
			<header style={{ background: 'lightblue' }}>
				<a href="">客户管理</a>
				<a href="">系统设置</a>
			</header>
			<main>
			    <HashRouter>
					<Switch>
						{/* <Route path='/' exact component={Custom} /> */}
						<Redirect from='/' exact to='/custom' /> 
						<Route path='/custom' component={Custom} />
						<Route path='/system' component={System} />
						{/* 做一个404处理:以上规则都不符合 */}
						{/* <Redirect to='/custom' /> */}
						<Route path='*' component={Error} />
					</Switch>
				</HashRouter>
			</main>
		</>;
	}
}

export default App;
  • HashRouter:HASH路由容器
  • Route:设置路规则

+ 路由特点一:

不管当前规则是否匹配,依然会向下匹配查找,而我们期望的是某一条规则匹配后,不再向下匹配(vue的路由天生就这样) => react路由可以把路由规则基于包裹起来即可

+ 路由特点二:

默认路由匹配的规则是不精准也不严格的,我们可以给规则上设置 exact(精准匹配) strict(严格匹配)/ Redirect:实现路由重定向

受路由管控组件的3个属性

基于<Route...>渲染的组件都是受路由管控的

受路由管控的组件,在属性中都有三个属性 this.props

HASH路由自己模拟了一套History Api的机制(历史记录池),每一次的路由切换和跳转都会向池子中追加一条记录

 history:{
     * length:记录历史记录池中的数量
     * go(n):跳转到指定的记录 go(-1)=>goBack() /go(1)=>goForward()
     * push:跳转到指定的路由地址,也是向池子中追加一条新的记录
            this.pros.history.push(xxx)
 }
 
 location:{
     pathname:跳转的路径地址;
     search:问号传参的信息
     hash:哈希值
     state:传递进来的信息
 }
 
 match:{} 存储一些路由解析地址后的规则和结果
  • 不受路由管控,默认属性中没有history/location等内容

     * 想让其变成受路由管控的,或者想要这些属性,只需要基于react-router-dom中的withRouter高阶组件代理一下即可;
     * 用withRouter代理的组件必须在HashRouter或者BrowserRouter中
    
export default withRouter(nav);

LINK vs navLink

不管是Link 还是NavLink都是为了实现路由的跳转(最后渲染为A标签)

  • Link 类似于普通A标签,通过Link中的to可以跳转到具体的路由页面
  • NavLink:会根据浏览器地址中的地址和NavLink指定的to中的地址进行匹配,如果匹配上,则会给A设置一个class='active'
to = '/';
to = {{
pathname: '/',
	search: '?xxx=xxx',
		hash: '#xxx'
}}

看以下组件

import React, { Component } from 'react';
import { Switch, Route, Redirect, Link, NavLink } from 'react-router-dom';
import CustomList from './Custom/CustomList';
import CustomHandle from './Custom/CustomHandle';

class Custom extends Component {
   render() {
   	return <>
   		<div className='menuBox'>
   			<link to='/custom/list'>我的客户</link>
   			<link to={{
   				pathname: '/custom/list',
   				search: '?lx=all'
   			}}>全部客户</link>
   			<link to='/custom/handle'>我的客户</link>
   		</div>
   		{/* 二级路由 */}
   		<Switch>
   			<Redirect from='custom' exact to='custom/list'/>
   			<Route path ='custom/list' Component={CumstomList}/>
   			<Route path ='custom/handle' exact Component={CumstomHandle}/>
   			<Route path ='custom/handle/:customId' Component={CumstomHandle}/>
   			<!--路径参数-->
       	        </Switch>
   	</>;
   }
}

子组件

class CustomList extends Component {
	render() {
		let search = this.props.location.search,
		    state = this.props.location.state;
		return <>
			客户列表 === {search ? '全部客户' : '我的客户'}
		</>;
	}
}


// ==========================

class CustomHandle extends Component {
	render() {
		return <>
	        	客户{this.props.match.params.customId?'修改':'新增'}
		</>
		// 路径参数:custom/handle/:customId =>custom/handle/100
		// =>this.props.match.params 在这里存储了路径参数
	}
}

NavLink

class Nav extends Component {
	render() {
		return <header style={{background:'lightblue'}} className = 'navbox'>
			<NavLink to='custom'>客户管理</NavLink>
			<NavLink to='system'>系统设置</NavLink>
		</header>
		// 路径参数:custom/handle/:customId =>custom/handle/100
		// =>this.props.match.params 在这里存储了路径参数
	}
}

export default withRouter(Nav);

可以给active设置样式

.headerBox{
	a{
		color:#000;
	}
	&.actve{
		color:red;
	}
}

Nav本身不受路由管控,默认实行中没有history/location等内容;

想让其变成受路由管控的,或者想要这些属性,只需基于react-router-dom中的withRouter高阶组件代理一下即可;

用withRouter代理的组件必须在HashRouter或BrowerRouter中