:::tips
原理:不同的路径对应不同的单文件组件,当路径发生变化的时候,我们需要切换对应的组件。
react-router-dom使用的组件
- HashRouter-hash的路由模式 底层原理是监听hashchange事件 实现组件的切换。
- BrowserRouter-history的路由模式 路由的底层原理是不一样的。
- Link组件-路由跳转的组件。
- NavLink组件-路由跳转的组件,可以自定义相关的样式。
- Route组件-组件的占位符。
- Switch组件-排他思想,在Switch组件中只匹配最开始的组件,其余的组件不再进行匹配。
- WithRouter高阶组件-使用路由将应用的组件进行包裹,并且可以将路由的相关参数传递过来。 :::
1 使用路由传递参数
:::info 传递参数的三种形式:
- “/detail/:id”对应的就是Detail组件,id就是传递的参数。”/detail/123”或者”/detail/abc”都可匹配上述的路径。
- search查询模式。”/detain?name=coderweiwei&age=19”,也是可以传递参数的。
to属性可以传递一个对象,我们可以将参数放在这个对象中,在路由之间进行传递。 :::
2 路由表的使用
:::info 路由表与组件是一一对应的关系,我们可以将这个关系单独提出来,使用一个配置文件的形式,这样的话,更加实用的话更加简洁、方便。 :::
2.1 原始嵌套路由的使用
index.js文件
// 需要使用BrowserRouter或者hashRouter对整个应用程序进行包裹,方便react-router将路由相关的属性传递都我们任意组件中去。
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import "./App.css";
import { BrowserRouter } from "react-router-dom";
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
// App组件
// 引入路由相关的组件 HashRouter
// import { HashRouter, Link, Route } from "react-router-dom";
// 使用history模式
import { Link, Route, Switch, withRouter } from "react-router-dom";
import Home from "./views/Home";
import About from "./views/About";
import Profile from "./views/Profile";
import Product from "./views/Product";
function App(props) {
const handleClick = () => {
console.log(props)
// 手动跳转路由
props.history.push("/product")
}
// 渲染函数
return (
<div className="App">
{/* 路由切换区域 */}
<Link to="/">首页</Link>
<Link to="/about">关于</Link>
<Link to="/profile">我的</Link>
<button onClick={handleClick}>商品展示</button>
{/* 路由展示区域 */}
<Switch>
<Route exact path='/' component={Home} />
<Route path="/about" component={About} />
<Route path='/profile' component={Profile} />
<Route path='/product' component={Product} />
</Switch>
</div>
);
}
export default withRouter(App);
// About嵌套子组件
import React, { PureComponent } from 'react'
import { NavLink, Route, Switch } from 'react-router-dom'
// 子组件
function Resume() {
return <h2>简历投递</h2>
}
// 子组件
function Culture() {
return <h2>文化建设</h2>
}
// 子组件
function Contract() {
return <h2>联系我们</h2>
}
// 子组件
function Join() {
return <h2>加入我们</h2>
}
export default class About extends PureComponent {
// 处理事件
joinUs() {
// 在子组件中 路由的相关属性通过组件的props传递过来了
console.log(this.props)
// 从属性中获取history对象
const { history } = this.props;
// 手动实现路由跳转
history.push("/about/join")
}
render() {
return (
<>
<h2>About组件</h2>
<hr />
{/* 导航的菜单 */}
<NavLink exact to="/about">简历投递</NavLink>
<NavLink to="/about/culture">文化建设</NavLink>
<NavLink to="/about/contract">联系我们</NavLink>
<button onClick={() => this.joinUs()}>加入我们</button>
<hr />
{/* 导航组件的占位符 */}
<Switch>
<Route exact path="/about" component={Resume} />
<Route path="/about/culture" component={Culture} />
<Route path="/about/contract" component={Contract} />
<Route path="/about/join" component={Join}/>
</Switch>
</>
)
}
}
2.2 使用路由表(统一路由配置)来展示路由
// 安装插件 新的路由表统一在单独的js文件中进行配置 然后统一导出
yarn add react-router-config
// 路由映射表
// 引入对应的组件
import About, { Contract, Culture, Join, Resume } from "../views/About";
import Home from "../views/Home"
import Product from "../views/Product";
import Profile from "../views/Profile";
const routes = [
{
path: '/',
exact: true,
component: Home
},
{
path: '/about',
component: About,
routes: [
{
path: '/about',
exact: true,
component: Resume
},
{
path: '/about/culture',
component: Culture
},
{
path: '/about/contract',
component: Contract
},
{
path: '/about/join',
component: Join
}
]
},
{
path: "/profile",
component: Profile
},
{
path: "/product",
component: Product
}
]
export default routes;
3 一级路由的配置
// 引入路由相关的组件 HashRouter
// import { HashRouter, Link, Route } from "react-router-dom";
// 使用history模式
import { Link, withRouter } from "react-router-dom";
// 使用react-router-config插件
import { renderRoutes } from "react-router-config";
// 引入需要渲染的路由表
import routes from "./router";
// import Home from "./views/Home";
// import About from "./views/About";
// import Profile from "./views/Profile";
// import Product from "./views/Product";
function App(props) {
console.log(props)
const handleClick = () => {
// 手动跳转路由
props.history.push("/product")
}
// 渲染函数
return (
<div className="App">
{/* 路由切换区域 */}
<Link to="/">首页</Link>
<Link to="/about">关于</Link>
<Link to="/profile">我的</Link>
<button onClick={handleClick}>商品展示</button>
{/* 路由展示区域 */}
{/* <Switch>
<Route exact path='/' component={Home} />
<Route path="/about" component={About} />
<Route path='/profile' component={Profile} />
<Route path='/product' component={Product} />
</Switch> */}
{/* 路由展示区域 使用react-router-config */}
{renderRoutes(routes)}
</div>
);
}
export default withRouter(App);
4 嵌套路由的配置
import React, { PureComponent } from 'react'
import { NavLink } from 'react-router-dom'
// 使用react-router-config
import { renderRoutes } from 'react-router-config'
// 引入需要渲染的路由表 已经在组件的属性上了 不需要引入了
// import routes from "../router";
// 子组件
export function Resume() {
return <h2>简历投递</h2>
}
// 子组件
export function Culture() {
return <h2>文化建设</h2>
}
// 子组件
export function Contract() {
return <h2>联系我们</h2>
}
// 子组件
export function Join() {
return <h2>加入我们</h2>
}
export default class About extends PureComponent {
// 处理事件
joinUs() {
// 在子组件中 路由的相关属性通过组件的props传递过来了
console.log(this.props)
// 从属性中获取history对象
const { history } = this.props;
// 手动实现路由跳转
history.push("/about/join")
}
render() {
// 获取react-router-config传递过来的路由映射表
console.log(this.props)
const routes = this.props.route.routes;
return (
<>
<h2>About组件</h2>
<hr />
{/* 导航的菜单 */}
<NavLink exact to="/about">简历投递</NavLink>
<NavLink to="/about/culture">文化建设</NavLink>
<NavLink to="/about/contract">联系我们</NavLink>
<button onClick={() => this.joinUs()}>加入我们</button>
<hr />
{/* 导航组件的占位符 */}
{/* <Switch>
<Route exact path="/about" component={Resume} />
<Route path="/about/culture" component={Culture} />
<Route path="/about/contract" component={Contract} />
<Route path="/about/join" component={Join}/>
</Switch> */}
{/* 使用react-router-config提供的函数来渲染路由表 */}
{ renderRoutes(routes) }
</>
)
}
}