1.改变页面路由的两种方式
监听hash的改变
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="app">
<a href="#/home">首页</a>
<a href="#/about">关于</a>
<div class="router-view"></div>
</div>
<script>
// 监听router-view DOM
const oDiv = document.getElementsByClassName('router-view')[0];
//监听URL的改变
window.addEventListener('hashchange', () => {
// console.log('hashchange', location.hash);
switch(location.hash) {
case "#/home":
oDiv.innerHTML = '首页';
break;
case "#/about":
oDiv.innerHTML = "关于";
break;
default:
oDiv.innerHTML = "";
}
})
</script>
</body>
</html>
hash的缺点: 路径里面有一个 “#”,看起来不像真实路径地址。
HTML5 history
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<div class="app">
<a href="/home">首页</a>
<a href="/about">关于</a>
<div class="router-view"></div>
</div>
<script>
const oDiv = document.getElementsByClassName('router-view')[0];
//取消a元素的默认行为
const aList = document.getElementsByTagName('a');
Array.from(aList).forEach( el => {
el.addEventListener('click', e => {
e.preventDefault();
// console.log('取消了a元素默认行为');
const href = el.getAttribute('href');
history.pushState({
},'',href)
urlChange()
} )
} )
function urlChange() {
switch(location.pathname) {
case "/home":
oDiv.innerHTML = '首页';
break;
case "/about":
oDiv.innerHTML = "关于";
break;
default:
oDiv.innerHTML = "";
}
}
// 执行返回操作的时候,路径变了,但是下面的内容没有变化
window.addEventListener('popstate',() => {
// console.log('popstate')
urlChange();
})
</script>
</body>
</html>
2.react-router
3.react-router 主要的api
4.react-router 基本使用
import React, {
PureComponent } from 'react'
import {
BrowserRouter,
Link,
Route
} from 'react-router-dom'
import Home from './pages/home'
import About from './pages/about'
import Profile from './pages/profile'
export default class App extends PureComponent {
render() {
return (
<div>
<BrowserRouter>
<Link to="/">首页</Link>
<Link to="/about">关于</Link>
<Link to="/profile">我的</Link>
<Route exact path="/" component={
Home}/>
<Route path="/about" component={
About}/>
<Route path="/profile" component={
Profile}/>
</BrowserRouter>
</div>
)
}
}
<Route exact path="/" component={
Home}/>
因为路径使用的是模糊匹配,所以加入exact可以实现精准匹配路由,不会出现渲染出我们不想要的页面。
5.react-router 深入解析
link都会渲染出来:并且都会显示为a标签
route不一定会显示,当页面的路由与route中的path想匹配的时候才会显示该路由下的页面。toute的位置我们可以自行决定。
navLink的使用
选中哪一个路径,就将对应的路径变为红色。
<NavLink exact to="/" activeStyle={
{
color:"red"}}>首页</NavLink>
<NavLink to="/about" activeStyle={
{
color:"red"}}>关于</NavLink>
<NavLink to="/profile" activeStyle={
{
color:"red"}}>我的</NavLink>
’
react-router switch的使用
当我们匹配某一个路径的时候,我们会发现一些问题。
比如: /about路径被匹配到的时候,最后一个组件noMatch也被匹配到了
但是我们在开发中有一种排他思想,只要匹配到了第一个组件,那么后面的组件就不想继续匹配了。这个时候,
我们就需要使用Switch来将所有的Route进行包裹就可以了。
- 代码示例
<BrowserRouter>
<NavLink exact to="/" activeStyle={
{
color:"red"}}>首页</NavLink>
<NavLink to="/about" activeStyle={
{
color:"red"}}>关于</NavLink>
<NavLink to="/profile" activeStyle={
{
color:"red"}}>我的</NavLink>
<Switch>
<Route exact path="/" component={
Home}/>
<Route path="/about" component={
About}/>
<Route path="/profile" component={
Profile}/>
<Route component={
noMatch}/>
</Switch>
</BrowserRouter>
react-router redirect的使用
当我们页面想要发生重定向的时候,就需要使用到redirect
这个操作经常会在我们登录页面也是用,当用户登录状态为true时,显示user页面,为false的时候,显示login页面。
代码示例:
export default class user extends PureComponent {
constructor(props){
super(props)
this.state = {
isLogin:true
}
}
render() {
return this.state.isLogin ? (
<div>
<h2>user</h2>
<h2>用户名: kangjiahao</h2>
</div>
) : <Redirect to="/login"/>
}
}
react-router 路由嵌套(二级,三级路由)
我们在开发中比较常见的一个路由的应用就是路由嵌套。
about下的路由就去about组件内部实现。 包括 以及
举个例子:
代码实现;
import React, {
PureComponent } from 'react'
import {
NavLink, Route, Switch } from 'react-router-dom'
function AboutHistory(props){
return <h2>企业成立于2000年,拥有悠久的历史。</h2>
}
function AboutCulture(props){
return <h2>创新 || 发展 || 共赢</h2>
}
function AboutUs(props){
return <h2>联系电话: 8888-9999-0000</h2>
}
export default class About extends PureComponent {
render() {
return (
<div>
<NavLink exact to="/about" activeStyle={
{
color:"gold",fontSize:'25px'}}>企业历史</NavLink>
<NavLink exact to="/about/history" activeStyle={
{
color:"gold",fontSize:'25px'}}>企业文化</NavLink>
<NavLink exact to="/about/us" activeStyle={
{
color:"gold",fontSize:'25px'}}>联系我们</NavLink>
<Switch>
<Route exact path="/about" component={
AboutHistory}/>
<Route exact path="/about/history" component={
AboutCulture}/>
<Route exact path="/about/us" component={
AboutUs}/>
</Switch>
</div>
)
}
}
手动跳转路由
<button onClick={
e => this.jumpToJion()}>加入我们</button>
jumpToJion(){
this.props.history.push('/about/jion');
}
react-router 参数传递
一般传递参数有三种方式:
第一种:动态路由传递参数
第二种:search方法传递(不建议使用)
传值: <NavLink to="/details?data=kangjiahao" activeStyle={
{
color:"red"}}>详情</NavLink>
获取值: console.log(this.props.location.search)
第三种:采用to 的方式 传入一个对象来实现传值(建议使用)
传值:
<NavLink to={
{
pathname:"/details",
search:"?name=abc",
state: this.state.data
}}
activeStyle={
{
color:"red"}}>详情</NavLink>
取值:
const location = this.props.location;
、console.log(location)
react-router 路由映射单独文件夹配置
安装单独的包:react-router-config
新建文件夹 -> router -> index.js
import Home from '../pages/home'
import About from '../pages/about'
import Profile from '../pages/profile'
import User from '../pages/user'
const routers = [
{
path:'/',
exact:true,
component: Home
},
{
path:'/about',
component: About
},
{
path:'/profile',
component: Profile
},
{
path:'/user',
component: User
}
]
export default routers;
二级路由写法:
二级路由写法代码示例:
import Home from '../pages/home'
import About,{
AboutHistory, AboutCulture, AboutUs, JionUs} from '../pages/about'
import Profile from '../pages/profile'
import User from '../pages/user'
const routers = [
{
path:'/',
exact:true,
component: Home
},
{
path:'/about',
component: About,
routes:[
{
path:'/about',
exact:true,
component:AboutHistory
},
{
path:'/about/history',
component:AboutCulture
},
{
path:'/about/us',
component:AboutUs
},
{
path:'/about/jion',
component:JionUs
}
]
},
{
path:'/profile',
component: Profile
},
{
path:'/user',
component: User
}
]
export default routers;
如何拿到封装好的路由里面的子路由:
this,props。route() 就可以拿到对应的子路由
使用二级路由:
引入函数renderRoutes
import {
renderRoutes } from 'react-router-config'
使用函数嵌套传递过来的route。即可
{
renderRoutes(this.props.route.routes)
}
{
/* <Switch>
<Route exact path="/about" component={AboutHistory}/>
<Route exact path="/about/history" component={AboutCulture}/>
<Route exact path="/about/us" component={AboutUs}/>
<Route exact path="/about/jion" component={JionUs}/>
</Switch> */}