路由:就是让不同的路径来渲染不同的组件, 两种实现方式
1、HashRouter:利用hash实现路由切换
2、BrowserRouter:H5 Api 实现路由的切换
1. hash实现路由切换
<a href="#/a">去a</a>
<a href="#/b">去b</a>
<script>
window.addEventListener('hashchange',(e)=>{ // 监听路由变化 hashchange
console.log(e)
console.log(window.location.hash); // #/a #/b
console.log(e.newURL) // http://localhost:3000/#/a
});
</script>
2. H5的History
3. react-router-dom
实现原理:两大组件 HashRouter 和 Route。
1)HashRouter 在组件挂载后(componentDidMount),通过 " hashChange " 监听 url 变化,拿到 hash 值,
window.addEventListener('hashchange',() => {
this.setState({
location:{
...this.state.location,
pathname:window.location.hash?window.location.hash.slice(1):'/'
}
})
})
2)再通过" context " 的 " Provider ",把 hash 值传给当前组件,即 Route,
<Provider value={value}>
{this.props.children}
</Provider>
然后Route 中的" context "的 " Consumer " 拿到 hash 值,将传过来的pathname 与 当前组件的path属性 比较,如果一样,就渲染组件
<Consumer>
{
value => {
let {location:{pathname}} = value;
let {path,component:Component} = this.props;
if(pathname === path){
return <Component />
} else {
return null
}
}
}
</Consumer>
import React,{Component} from 'react';
import {Provider} from './context'
//每当地址栏里的 锚点发生改变的时候 都需要重新匹配
export default class HashRouter extends Component{
state={
location:{
pathname:window.location.hash?window.location.hash.slice(1):'/'
}
}
componentDidMount(){
window.addEventListener('hashchange',() => {
this.setState({
location:{
...this.state.location,
pathname:window.location.hash?window.location.hash.slice(1):'/'
}
})
})
}
render(){
let value={
location:this.state.location
}
return (
<Provider value={value}>
{this.props.children}
</Provider>
)
}
}
4.路径转换正则
npm i path-to-regexp -S