1. js(BOM)思路写法(不采用)
前提:写Home,About两个页面组件
App中导入:import React, { useEffect,useState } from ‘react’
let [route,setRoute] = useState(window.location.hash.substr(1))
useEffect(() => { //在页面初始化时对于路由进行监听
window.addEventListener('hashchange', () => {
//改变路由的时候把数据存储
setRoute( window.location.hash.substr(1));
})
})
let Child //声明组件代理
//router变化会执行一次 改变Child组件
switch (route) {
case '/about': Child = About; break;
case '/home': Child = Inbox; break;
default: Child = Home;
}
return (
<div>
<h1>App</h1>
<ul>
{/* 通过点击事件,a标签的锚点原理,改变路由*/}
<li><a href="#/about">About</a></li>
<li><a href="#/Home">Home</a></li>
</ul>
{/* 渲染Child组件,实际上渲染的是switch选择的组件 */}
<Child />
</div>)
}
以下下载:npm i react-router-dom@5 -D
2.采用react-router-dom@5中Link与Route(不采用)
引入:import { Link,Route} from “react-router-dom”;
前提:引入Home,About两个页面组件
App.jsx中:
导航栏:
//导航栏中的写法
//<Link to="/路由名">导航名字</Link>
<Link to="/about">About</Link>
<Link to="/Home">Home</Link>
渲染页面:
//渲染页面的写法
//<Route path={'/路由名(与上边对应)'} component={页面组件名字} />
<Route path={'/about'} component={About} />
<Route path={'/Home'} component={Home} />
main.jsx中:(以下均有这个操作)
//引入 BrowserRouter(history模式路由)/HashRouter(Hash模式路由)
import { BrowserRouter } from "react-router-dom";
//使用:将使用路由组件包裹
<BrowserRouter>
<App/>
</BrowserRouter>
3.采用react-router-dom@5中NavLink与Route(推荐)
引入:import { Link,Route} from “react-router-dom”;
前提:引入Home,About两个页面组件
App.jsx中:
导航栏(activeClassName,activeStyle):
//导航栏中的写法
//<NavLink to="/路由名">导航名字</NavLink>
//activeClassName 创建选中样式类名
//activeStyle={{???}} 单独创建选中时的样式
<NavLink activeClassName="???" activeStyle={{
fontWeight: 'bold',
color: 'red'
}} to="/about">About</NavLink>
<NavLink activeClassName="???" to="/Home">Home</NavLink>
渲染页面:(解决模糊匹配exact)
<Route path={'/about'} component={About} />
<Route exact path={'/Home/a'} component={Home1} />
//此处上方已经有/Home/a 下方有/Home 如果此刻路由是/Home的话,就会直接访问/Home/a和/Home,页面上会渲染两个,此时解决方案:1.切换两者位置2.添加精准匹配exact属性,只有完全一样才会匹配
<Route path={'/Home'} component={Home} />
(只匹配一个 Switch):
<Switch>
<Route path={'/about'} component={About} />
{/*在匹配/home时会直接匹配,在Switch标签中,只会匹配一个,不会因为模糊匹配多个*/}
<Route path={'/home'} component={Home} />
<Route path={'/home/a'} component={A} />
</Switch>
4.页面的重定向(解决页面初始加载问题)
//设定重新加载某地址
//引入:
import {Redirect } from 'react-router-dom'
<Redirect from='/需要被重定向地址' to='/被重定向的地址'/>
5.嵌套路由(二级路由)
路由结构:
-Home
-Info
-List
-About
-aaa
-bbb
一级路由:(在App.jsx中的)
//导航栏内容
<NavLink to={'/about'}>about</NavLink>
<NavLink to={'/home'}>home</NavLink>
//渲染页面
<Switch>
<Route path={'/about'} component={About} />
<Route path={'/home'} component={Home} />
<Redirect exact from='/' to={'/home'}/>
</Switch>
二级路由(Home中):[其实一级二级都是一样的,路由地址+渲染界面]
//路由地址必须写全
<NavLink to={'/home/info'}>信息页面info</NavLink>
<NavLink to={'/home/list'}>列表</NavLink>
<Switch>
<Route path={'/home/info'} component={Info}/>
<Route path={'/home/list'} component={List}/>
<Redirect from={'/home'} to={'/home/info'} />
</Switch>
6.路由传参(params参数)
6.1.传递参数:params传参(路由只显示值)
<NavLink to={`/home/list/${item.id}/${item.text}`}>{item.text}</NavLink>
//模板字符串+/传递参数值
<NavLink to={`路由地址${2333}/${666}`}>{item.text}</NavLink>
<Switch>
{/* /home/list/:id/:title params参数定义key */}
<Route path={'/home/list/:id/:title'} component={Item}></Route>
</Switch>
接收参数:(点击路由链接生效)
//函数式组件中直接形参的.match.params即为对应的传递参数对象
export default function Item(props) {
console.log(props);
let {id,title} = props.match.params;
return (
<div>
<p>id: {id}</p>
<p>title:{title}</p>
</div>
)
}
6.2.传递参数:search传参(相当于get拼接字符串,路由显示参数+值)
<NavLink to={`/home/list?id=${3333}&title=${23233}`}>{item.text}</NavLink>
//路由?参数=值&参数=值......
<Switch>
<Route path={'/home/list'} component={Item}></Route>
</Switch>
接收参数:
export default function Item(props) {
console.log(props);
let str = props.location.search;
//=============复杂写法============
str = str.split("?")[1].split("&")
let obj = {}
str.forEach(v => {
let arr = v.split("=")
console.log(arr)
obj[arr[0]] = arr[1]
})
let {id,title} = obj
//============简餐写法=============
let {id,title} = qs(obj) //react内置的处理location.search方法中的值
return (
<div>
<p>id: {id}</p>
<p>title:{title}</p>
</div>
)
}
![[Pasted image 20230714231324.png]]
6.3.传递参数:state传参(路由不显示参数,值)
<NavLink to={{ pathname: '/home/list', state: { id: 555, title: 666 } }}>{item.text}</NavLink>
//to={{pathname:路由地址,state:{参数:值,参数:值}}}
<Switch>
<Route path={'/home/list'} component={Item}></Route>
</Switch>
接收参数:
export default function Item(props) {
let {id,title} = props.location.state || {}
return (
<div>
<h1>list detal</h1>
<p>id: {id}</p>
<p>title:{title}</p>
</div>
)
}
7.封装(一级)路由
编写reouter.js:
import Center from '../pages/Center/Center'
import Cinemas from '../pages/Cinemas/Cinemas';
import Films from '../pages/Films/Films';
import Order from '../pages/Center/Order/Order'
import Maney from '../pages/Center/Maney/Maney'
import Setting from '../pages/Center/Setting/Setting'
import Login from '../pages/Login/Login';
export const routes = [{
path: '/films',
component:Films,
meta:{
title:"电影",
id:1,
auth:false,
},
}, {
path: '/cinemas',
component:Cinemas,
meta: {
title:'影院',
id:2,
auth:false,
}
}, {
path: '/center',
component:Center,
meta: {
title:'我的',
id:3,
auth:false
}
},{
path: '/order',
component:Order,
meta: {
title:'',
id:4,
auth:true
}
},{
path: '/maney',
component:Maney,
meta: {
title:"",
id:5,
auth:true
}
},{
path: '/setting',
component:Setting,
meta: {
title:'',
id:6,
auth:true
}
},{
path: '/login',
component:Login,
meta: {
title:'',
id:6,
auth:false
}
},
]
编写路由:
<ul>
{
routes.map(route => {
if (route.meta.title.trim() !== '') {
return (
<li key={route.meta.id}>
<NavLink to={route.path}>{route.meta.title}</NavLink>
</li>
)
}
})
}
</ul>
<Switch>
{
routes.map(route => {
return (
<Route key={route.meta.id} path={route.path} route.component></Route>)
})
}
<Redirect exact from="/" to="films"></Redirect>
</Switch>