:::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-configimport { 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) }</>)}}
