脚手架编译打包出来的是 SPA 单页面应用 所依赖的核心就是前端路由
npm i react-router-dom@5
- // 相当于 main.js
-
- import React from 'react';
- import ReactDOM from 'react-dom/client';
- import './index.css';
- import App from './App';
- import {HashRouter,BrowserRouter} from 'react-router-dom'
- import reportWebVitals from './reportWebVitals';
-
- const root = ReactDOM.createRoot(document.getElementById('root'));
- root.render(
- // React.StrictMode 标签 严格模式 检查
- <React.StrictMode>
- <HashRouter>
- <App />
- HashRouter>
- React.StrictMode>
- );
-
- // 页面性能分析 需要 web-vitals库的支持
- reportWebVitals();
react-router-dom 一些内置组件使用的介绍:
- //import axios from 'axios';
- import React, { Component } from 'react'
- import './App.css';
- import {NavLink,Route,Switch,Redirect} from 'react-router-dom'
- import Home from './component/Home'
- import About from './component/About'
- import Formerly from './component/Formerly'
- import Case from './page/Case'
- import MyNavLink from './component/MyNavLink'
- export default class App extends Component {
- render(){
- return (
- <div className="container">
- <div className="row">
- <div className="col-xs-offset-2 col-xs-8">
- <div className="page-header"><h2>React Router Demoh2>div>
- div>
- div>
- <Formerly a={8755}/>
- <div className="row">
- <div className="col-xs-2 col-xs-offset-2">
- <div className="list-group">
- <NavLink className='list-group-item' to='/about'>AboutNavLink>
- <NavLink className='list-group-item' to='/home'>HomeNavLink>
- <NavLink className='list-group-item' to='/case'>CaseNavLink>
- 自己封装:
- <MyNavLink to="about/b/c">关于MyNavLink>
- <MyNavLink to="home">首页MyNavLink>
- <MyNavLink to="case" children="案例">MyNavLink>
- 模糊匹配精准匹配
- div>
- div>
- <div className="col-xs-6">
- <div className="panel">
- <div className="panel-body">
- <Switch>
- <Route path='/about' exact component={About}>Route>
- <Route path='/home' component={Home}>Route>
- <Route path='/case' component={Case}>Route>
- <Route path='/about' component={Formerly}>Route>
- <Redirect to="/home"/>
- Switch>
- div>
- div>
- div>
- div>
- Redirect写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由 <br>br>
- 普通about 开启了严格匹配 Formerly没有开启 所以 about/b/c 关于 会导向 Formerly
- div>
- )
- }
- }
相同的类名比较多时可以 自行封装一下 接收到的props 直接展开到 组件中
传入 children 就是写入标签内的数据
- import React, { Component } from 'react'
- import { NavLink } from 'react-router-dom'
-
- export default class index extends Component {
- render() {
- return (
- <NavLink {...this.props} className="list-group-item">NavLink>
- )
- }
- }
1.写法不同 引用方式不同
一般组件:
手动固定引入 路由组件:
用到时再加载
2.接收到的props不同:
一般组件:写组件标签时传递了什么,就能收到什么
路由组件:接收到三个固定的属性 history location match
1.注册子路由时要写上父路由的path值
2.路由的匹配是按照注册路由的顺序进行的
这里以 Case组件为例
- import React, { Component } from 'react'
- import New from './New'
- import Message from './Message'
- import { Link,Route } from 'react-router-dom'
-
- export default class Case extends Component {
- render() {
- //console.log('路由组件会有默认props',this.props,'这里也执行了两次?')
- return (
- <div>
- <h3>
- Case组件是保存在 page里的路由组件
- <br />
- 这里显示的是嵌套路由
- h3>
- <Link to='/case/new'>新闻Link>
- <Link to='/case/message'>消息Link>
- <Route path="/case/new" component={New}>Route>
- <Route path="/case/message" component={Message}>Route>
- div>
- )
- }
- }
1.params 传参
路径跳转时直接写上 数据 / 分割
美食
匹配展示时 要接上占位符 :标识
在跳转的组件内部 this.props.match.params 解构出来 使用
const {id,title} = this.props.match.params
2.search 传参
相当于url中的query字符串 ?开始 &分隔
汽车
匹配展示时不用添加参数
接收 search 参数 在 this.props.location 里 但它是查询字符转 想用要转化成对象
const {search} = this.props.location
3.state传参
单独写对象 pathname 路径名 state传递的参数分开
娱乐
匹配展示时不用添加参数
接收 state 参数 在 this.props.location 里 它不会显示在地址栏
const {id,title} = this.props.location.state
完整代码:
Case/New
- import React, { Component } from 'react'
- import { Link,Route } from 'react-router-dom'
- import Detail from './Detail'
-
- export default class New extends Component {
- state={
- NewArr:[
- {id:"101",title:'新闻1'},
- {id:"201",title:'新闻2'},
- {id:"301",title:'新闻3'}
- ]
- }
-
- pushS = (id,title) =>{
- // push跳转 携带 state参数
- this.props.history.push('/case/new/detail',{id,title})
-
- // search
- //this.props.history.push(`/case/new/detail?id=${id}&title=${title}`)
-
- // params
- //this.props.history.push(`/case/new/detail/${id}/${title}`)
- }
-
- replaceS = (id,title) => {
- // replace跳转 携带 state参数
- this.props.history.replace('/case/new/detail',{id,title})
-
- // search
- //this.props.history.replace(`/case/new/detail?id=${id}&title=${title}`)
-
- // params
- //this.props.history.push(`/case/new/detail/${id}/${title}`)
- }
-
-
-
-
- render() {
- const {NewArr} = this.state
- return (
- <div>
- <ul>
- {
- NewArr.map((x) =>{
- return (
- <li key={x.id}>
- {/**
- * 向组件传递 params 参数
- * <Link to={`/case/new/detail/${x.id}/${x.title}`}>{x.title}Link>
- * 向组件传递 search 参数
- * <Link to={`/case/new/detail?id=${x.id}&title=${x.title}`}>{x.title}Link>
- * state
- *
- */}
- <Link to={{pathname:'/case/new/detail',state:{id:x.id,title:x.title}}}>{x.title}Link>
- <button onClick={() => this.pushS(x.id,x.title)}>push编程跳转路由button>
- <button onClick={() => this.replaceS(x.id,x.title)}>replace编程跳转路由button>
- li>
- )
- })
- }
- ul>
-
- <hr />
- {/** 声明接收 params 参数
- * <Route path="/case/new/detail/:id/:title" component={Detail}>Route>
- * search 参数无需声明接收 正常注册路由即可
- * state 参数无需声明接收 正常注册路由即可
- *
- */}
- <Route path="/case/new/detail" component={Detail}>Route>
- div>
- )
- }
- }
Detail:
- import React, { Component } from 'react'
- //import qs from 'querystring'
-
- const DetailData = [
- {id:"101",context:'鼎立中原'},
- {id:"201",context:'哑铃战术'},
- {id:"301",context:'西南追歼'},
- ]
-
- export default class Detail extends Component {
- render() {
- console.log(this.props)
-
- // 接收params 参数
- // const {id,title} = this.props.match.params
-
- // 接收 search 参数
- // const {search} = this.props.location
- // const {id,title} = qs.parse(search.slice(1))
-
- // 接收 state 参数
- const {id,title} = this.props.location.state
-
- const findRes = DetailData.find(x =>{
- return x.id === id
- })
- return (
- <ul>
- <li>ID:{id}li>
- <li>TITLE:{title}li>
- <li>{JSON.stringify(findRes)}li>
- ul>
- )
- }
- }
之前都是通过 Link NavLink 来实现跳转 这是声明式导航
也可以利用API实现 编程式导航
使用场景:满足条件自动跳转、定时器事件满后自动跳转......
this.props.history.replace() replace 跳转 直接替换
this.props.history.goBack() 退后一步
this.props.history.goForward() 前进一步
this.props.history.go() 填写数字 正数前进 负数退后
也可以 携带 三种参数
- pushS = (id,title) =>{
- // push跳转 携带 state参数
- this.props.history.push('/case/new/detail',{id,title})
-
- // search
- //this.props.history.push(`/case/new/detail?id=${id}&title=${title}`)
-
- // params
- //this.props.history.push(`/case/new/detail/${id}/${title}`)
- }
-
- replaceS = (id,title) => {
- // replace跳转 携带 state参数
- this.props.history.replace('/case/new/detail',{id,title})
-
- // search
- //this.props.history.replace(`/case/new/detail?id=${id}&title=${title}`)
-
- // params
- //this.props.history.push(`/case/new/detail/${id}/${title}`)
- }