react路由:
路由传参params、search、state(含二级路由和三级路由)
一、准备工作:
1、创建myProject05-router目录
2、创建清单文件, npm init -y
3、安装第三方依赖包,npm install react react-dom react-scripts react-router-dom@5 --save
4、创建public文件夹,在该文件夹下创建index.html
5、创建src文件夹,在该文件夹下创建:
(1)入口文件index.js
(2)组件App.js和App.css文件
(3)pages文件夹,在该文件夹下创建Home文件夹
(4)Home文件夹下创建Cates文件夹(Cates.jsx)、Goods文件夹(Goods.jsx、Goods.css、Detail文件夹(Detail.jsx))、Home.jsx、Home.css
(5)About.jsx、Resolve.jsx
6、工程目录:
二、编写代码:
1、index.html:
<div id="root"></div>
2、index.js:
import ReactDOM from 'react-dom/client'
import App from './App'
import {
BrowserRouter} from 'react-router-dom'
const root = ReactDOM.createRoot(document.getElementById('root'))
root.render(
<BrowserRouter>
<App/>
</BrowserRouter>
)
3、App.js:
import React, {
Component } from 'react'
import {
NavLink, Redirect, Route, Switch} from 'react-router-dom'
import About from './pages/About'
import Home from './pages/Home/Home'
import Resovle from './pages/Resovle'
import './App.css'
export default class App extends Component {
render() {
return (
<div className='app'>
{
/* 制作导航菜单 */}
<div className='tabs'>
<NavLink to='/home'>首页</NavLink>
<NavLink to='/resovle'>解决方案</NavLink>
<NavLink to='/about'>关于我们</NavLink>
</div>
{
/* 注册路由(其实就是路径和组件的映射关系) */}
{
/* 精准匹配 */}
<Switch>
<Route path='/home' component={
Home}/>
<Route path='/resovle' component={
Resovle}/>
<Route path='/about' component={
About}/>
<Redirect to='/home'/>
</Switch>
</div>
)
}
}
4、App.css:
.app {
width: 400px;
margin: 10px auto;
}
.tabs {
display: flex;
flex-direction: rows;
}
.tabs a{
flex: auto;
padding: 10px 30px ;
background-color: #777;
color: white;
margin-right: 1px;
text-decoration: none;
}
5、Home.jsx:
import React, { Component } from 'react'
import { NavLink, Redirect, Route, Switch } from 'react-router-dom'
import Cates from './Cates/Cates'
import Goods from './Goods/Goods'
import './Home.css'
export default class Home extends Component {
render() {
return (
<div className='home'>
<div className='left'>
<NavLink to='/home/cates'>分类</NavLink>
<NavLink to='/home/goods'>商品</NavLink>
</div>
<div className='right'>
<Switch>
{/*二级路由 - 需要在前面加上一级路由的路径才可以找到*/}
<Route path='/home/cates' component={Cates}/>
<Route path='/home/goods' component={Goods}/>
<Redirect to='/home/goods'/>
</Switch>
</div>
</div>
)
}
}
6、Home.css:
.home {
margin-top: 10px;
display: flex;
flex-direction: rows;
height: 200px;
}
.home .left {
display: flex;
width: 120px;
flex-direction: column;
background-color: skyblue;
margin-right: 1px;
}
.home .left a {
text-decoration: none;
color: #333;
padding: 10px 0;
text-align: center;
}
.home .left .active {
background-color: orange;
}
.home .right {
flex: auto;
background-color: greenyellow;
}
7、About.jsx:
import React, { Component } from 'react'
export default class About extends Component {
render() {
return (
<div>这是关于我们内容</div>
)
}
}
8、Resovle.jsx:
import React, { Component } from 'react'
export default class Resovle extends Component {
render() {
return (
<div>这是解决方案内容</div>
)
}
}
9、Cates.jsx:
import React, { Component } from 'react'
export default class Cates extends Component {
render() {
return (
<div>分类组件内容</div>
)
}
}
10、Goods.css:
.goods .list{
display: flex;
justify-content: space-around;
background-color: plum;
}
.goods .list a {
text-decoration: none;
color: #333;
margin: 10px;
}
示例一:params方法传递参数:
11、Goods.jsx:
import React, { Component } from 'react'
import { Link, Route } from 'react-router-dom'
import Detail from './Detail/Detail'
import './Goods.css'
export default class Goods extends Component {
state = {
googList: [
{ id: 1, title: 'AAA', desc: 'aaaaaaaaaaaaaa' },
{ id: 2, title: 'BBB', desc: 'bbbbbbbbbbbbbb' },
{ id: 3, title: 'CCC', desc: 'cccccccccccccc' }
]
}
render() {
return (
<div className='goods'>
<div className='list'>
{
{/*
路由链接(携带参数): <Link to=`/home/goods/detail/${e.id}`>标题</Link>
注册路由(声明接收): <Route path='/home/goods/detail/:id' component={Detail} />
接收参数:this.props.match.params
*/}
this.state.googList.map(e => <Link key={e.id} to={`/home/goods/detail/${e.id}`}>{e.title}</Link>)
}
</div>
{/* 三级路由 - 需要在前面加上二级路由的路径才可以找到*/}
<Route path='/home/goods/detail/:id' component={Detail} />
</div>
)
}
}
12、Detail.jsx:
import React, { Component } from 'react'
export default class Detail extends Component {
getDataById = id => {
const data = [
{ id: 1, title: 'AAA', desc: 'aaaaaaaaaaaaaa' },
{ id: 2, title: 'BBB', desc: 'bbbbbbbbbbbbbb' },
{ id: 3, title: 'CCC', desc: 'cccccccccccccc' }
]
return data.find(e => e.id == id)
}
render() {
const { id } = this.props.match.params
const goodsDetail = this.getDataById(id)
return (
<div>
<p>id: {goodsDetail.id}</p>
<p>title: {goodsDetail.title}</p>
<p>desc: {goodsDetail.desc}</p>
</div>
)
}
}
示例二:search方法传递参数:
使用search方法,获取到的是’?id=1’字符串,这时可以借助第三方包query-string(npm install query-string --save)解析url字符串。
eg. let {id} = queryString.parse(this.props.location.search) :把url字符串转换成对象
11、Goods.jsx:
import React, { Component } from 'react'
import {Link, Route} from 'react-router-dom'
import Detail from './Detail/Detail'
import './Goods.css'
export default class Goods extends Component {
state = {
googList:[
{id:1,title:'AAA',desc:'aaaaaaaaaaaaaa'},
{id:2,title:'BBB',desc:'bbbbbbbbbbbbbb'},
{id:3,title:'CCC',desc:'cccccccccccccc'}
]
}
render() {
return (
<div className='goods'>
<div className='list'>
{
{/*
路由链接(携带参数): <Link to=`/home/goods/detail?id=${e.id}`>标题</Link>
注册路由(无需声明,正常注册即可): <Route path='/home/goods/detail' component={Detail} />
接收参数:this.props.location.search
备注:获取到的search时urlencoded编码字符串,需要借助第三方包query-string解析
*/}
this.state.googList.map( e => <Link key={e.id} to={`/home/goods/detail?id=${e.id}`}>{e.title}</Link>)
}
</div>
<Route path='/home/goods/detail' component={Detail}/>
</div>
)
}
}
12、Detail.jsx:
import React, { Component } from 'react'
import queryString from 'query-string'
export default class Detail extends Component {
getDataById = id => {
const data = [
{ id: 1, title: 'AAA', desc: 'aaaaaaaaaaaaaa' },
{ id: 2, title: 'BBB', desc: 'bbbbbbbbbbbbbb' },
{ id: 3, title: 'CCC', desc: 'cccccccccccccc' }
]
return data.find(e => e.id == id)
}
render() {
let {id} = queryString.parse(this.props.location.search)
let goodsDetail = this.getDataById(id)
return (
<div>
<p>id: {goodsDetail.id}</p>
<p>title: {goodsDetail.title}</p>
<p>desc: {goodsDetail.desc}</p>
</div>
)
}
}
示例三:state方法传递参数:
11、Goods.jsx:
import React, { Component } from 'react'
import { Link, Route } from 'react-router-dom'
import Detail from './Detail/Detail'
import './Goods.css'
export default class Goods extends Component {
state = {
googList: [
{ id: 1, title: 'AAA', desc: 'aaaaaaaaaaaaaa' },
{ id: 2, title: 'BBB', desc: 'bbbbbbbbbbbbbb' },
{ id: 3, title: 'CCC', desc: 'cccccccccccccc' }
]
}
render() {
return (
<div className='goods'>
<div className='list'>
{
{/*
路由链接(携带参数): <Link to={
{ pathname: '/home/goods/detail', state: { id: e.id } }}>标题</Link>
注册路由(无需声明,正常注册即可): <Route path='/home/goods/detail' component={Detail} />
接收参数:this.props.location.state
备注:刷新时参数保留
*/}
// pathname -> 路径 state -> 传的id值放在state中
this.state.googList.map(e => <Link key={e.id} to={
{ pathname: '/home/goods/detail', state: { id: e.id } }}>{e.title}</Link>)
}
</div>
<Route path='/home/goods/detail' component={Detail} />
</div>
)
}
}
12、Detail.jsx:
import React, { Component } from 'react'
export default class Detail extends Component {
getDataById = id => {
const data = [
{ id: 1, title: 'AAA', desc: 'aaaaaaaaaaaaaa' },
{ id: 2, title: 'BBB', desc: 'bbbbbbbbbbbbbb' },
{ id: 3, title: 'CCC', desc: 'cccccccccccccc' }
]
return data.find(e => e.id == id)
}
render() {
// console.log(this.props.location.state);
let { id } = this.props.location.state
let goodsDetail = this.getDataById(id)
return (
<div>
<p>id: {goodsDetail.id}</p>
<p>title: {goodsDetail.title}</p>
<p>desc: {goodsDetail.desc}</p>
</div>
)
}
}
13、运行结果静态图示例:
三、运行命令
简化版:
在清单文件中添加一行命令 “start”: “react-scripts start”
运行命令:npm start
"scripts": {
"start": "react-scripts start",
"test": "echo \"Error: no test specified\" && exit 1"
}
<p>title: {goodsDetail.title}</p>
<p>desc: {goodsDetail.desc}</p>
</div>
)
}
}
13、运行结果静态图示例:
[外链图片转存中...(img-yyWH1Sju-1659573277958)]
### `三、运行命令`
[npm react-scripts satrt]()
简化版:
在清单文件中添加一行命令 ["start": "react-scripts start"]()
运行命令:[npm start]()
```json
"scripts": {
"start": "react-scripts start",
"test": "echo \"Error: no test specified\" && exit 1"
}