[尚硅谷React笔记]——第5章 React 路由
目录:
- 对SPA应用的理解
- 对路由的理解
- 前端路由原理
- 路由的基本使用
- 路由组件与一般组件
- NavLink的使用
- 封装NavLink组件
- Switch的使用
- 解决样式丢失问题
- 路由的模糊匹配与严格匹配
- Redirect的使用
- 嵌套路由
- 向路由组件传递params参数
- 向路由组件传递search参数
- .向路由组件传递state参数
- 总结路由参数
- push与repalce
- 编程式路由导航
- withRouter的作用
- BrowserRouter与HashRouter
1.对SPA应用的理解
- 单页Web应用(single page web application,SPA)。
- 整个应用只有一个完整的页面。
- 点击页面中的链接不会刷新页面,只会做页面的局部更新。
- 数据都需要通过ajax请求获取, 并在前端异步展现。
2.对路由的理解
什么是路由?
- 一个路由就是一个映射关系(key:value)
- key为路径, value可能是function或component
路由分类
- 后端路由:
- 理解: value是function, 用来处理客户端提交的请求。
- 注册路由: router.get(path, function(req, res))
- 工作过程:当node接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来处理请求, 返回响应数据
- 前端路由:
- 浏览器端路由,value是component,用于展示页面内容。
- 注册路由: <Route path="/test" component={Test}>
- 工作过程:当浏览器的path变为/test时, 当前路由组件就会变为Test组件
3.前端路由原理
前端路由的基石.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>前端路由的基石_history</title>
</head>
<body><a href="http://www.atguigu.com" onclick="return push('/test1') ">push test1</a><br><br><button onClick="push('/test2')">push test2</button><br><br><button onClick="replace('/test3')">replace test3</button><br><br><button onClick="back()"><= 回退</button><button onClick="forword()">前进 =></button><script type="text/javascript" src="https://cdn.bootcss.com/history/4.7.2/history.js"></script><script type="text/javascript">// let history = History.createBrowserHistory() //方法一,直接使用H5推出的history身上的APIlet history = History.createHashHistory() //方法二,hash值(锚点)function push (path) {history.push(path)return false}function replace (path) {history.replace(path)}function back() {history.goBack()}function forword() {history.goForward()}history.listen((location) => {console.log('请求路由路径变化了', location)})</script>
</body>
</html>
4.路由的基本使用
- 明确好界面中的导航区、展示区
- 导航区的a标签改为Link标签 <Link to="/xxxxx" >Demo</Link>
- 展示区写Route标签进行路径的匹配<Route path='/xxxx 'component={Demo}/>
- <App>的最外侧包裹了一个<BrowserRouter>或<HashRouter>
App.js
import React, {Component} from 'react';
import {Link, Route} from "react-router-dom";
import About from "./components/About/About";
import Home from "./components/Home/Home";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><div className="page-header"><h2>React Router Demo</h2></div></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><Link className="list-group-item" to="/about">About</Link><Link className="list-group-item" to="/home">Home</Link></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route></div></div></div></div></div>);}
}export default App;
index.js
import React from 'react';
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>
);
About.jsx
import React, {Component} from 'react';class About extends Component {render() {return (<div><h3>我是About的内容</h3></div>);}
}export default About;
Home.jsx
import React, {Component} from 'react';class Home extends Component {render() {return (<div><h3>我是Home的内容</h3></div>);}
}export default Home;
运行结果:

5.路由组件与一般组件
- 写法不同:
- 一般组件: <Demo/ >
- 路由组件: <Route path="/demo" component={Demo}/>
- 存放位置不同:
- 一般组件:components
- 路由组件: pages
- 接收到的props不同:
- 一般组件:,写组件标签时传递了什么,就能收到什么
- 路由组件:接收到三个固定的属性
- history:
- go: f go(n)
- goBack: f goBack()
- goForward: f goForward()
- push: f push(path,state)
- replace: f replace(path, state)
-
location:
- pathname: "/about"
- search: ""
- state: undefined
-
match:|
- params: {}
- path: "/about"
- url: "/about"
- history:
6.NavLink的使用
Header.jsx
import React, {Component} from 'react';class Header extends Component {render() {// console.log('Header组件收到的props是', this.props)return (<div><div className="page-header"><h2>React Router Demo</h2></div></div>);}
}export default Header;
About.jsx
import React, {Component} from 'react';class About extends Component {render() {// console.log('About组件收到的props是', this.props)return (<div><h3>我是About的内容</h3></div>);}
}export default About;
Home.jsx
import React, {Component} from 'react';class Home extends Component {render() {return (<div><h3>我是Home的内容</h3></div>);}
}export default Home;
App.js
import React, {Component} from 'react';
import {NavLink, Route} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><NavLink activeClassName="atguigu" className="list-group-item" to="/about">About</NavLink><NavLink activeClassName="atguigu" className="list-group-item" to="/home">Home</NavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route></div></div></div></div></div>);}
}export default App;
index.js
import React from 'react';
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>
);
index.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="utf-8"/><link rel="icon" href="%PUBLIC_URL%/favicon.ico"/><meta name="viewport" content="width=device-width, initial-scale=1"/><meta name="theme-color" content="#000000"/><metaname="description"content="Web site created using create-react-app"/><link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png"/><link rel="manifest" href="%PUBLIC_URL%/manifest.json"/><link rel="stylesheet" href="css/bootstrap.css"><style>.atguigu {background-color: orange !important;color: white !important;}</style><title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
项目结构:

运行结果:

7.封装NavLink组件
NavLink与封装NavLink
- NavLink可以实现路由链接的高亮,通过activeclassName指定样式名
- 标签体内容是一个特殊的标签属性
- 通过this.props.children可以获取标签体内容
App.js
import React, {Component} from 'react';
import {NavLink, Route} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";
import MyNavLink from "./components/MyNavLink/MyNavLink";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><MyNavLink to="/about" a={1} b={2} c={3}>About</MyNavLink><MyNavLink to="/home">Home</MyNavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route></div></div></div></div></div>);}
}export default App;
index.js
import React from 'react';
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>
);
Header.jsx
import React, {Component} from 'react';class Header extends Component {render() {// console.log('Header组件收到的props是', this.props)return (<div><div className="page-header"><h2>React Router Demo</h2></div></div>);}
}export default Header;
MyNavLink.jsx
import React, {Component} from 'react';
import {NavLink} from "react-router-dom";class MyNavLink extends Component {render() {console.log(this.props)return (<div><NavLink activeClassName="atguigu" className="list-group-item" {...this.props}/></div>);}
}export default MyNavLink;
About.jsx
import React, {Component} from 'react';class About extends Component {render() {// console.log('About组件收到的props是', this.props)return (<div><h3>我是About的内容</h3></div>);}
}export default About;
Home.jsx
import React, {Component} from 'react';class Home extends Component {render() {return (<div><h3>我是Home的内容</h3></div>);}
}export default Home;
项目结构:

运行结果:

8.Switch的使用
- 通常情况下,path和component是一一对应的关系。
- Switch可以提高路由匹配效率(单一匹配)。
Test.jsx
import React, {Component} from 'react';class Test extends Component {render() {return (<div><h2>Test...</h2></div>);}
}export default Test;
App.js
import React, {Component} from 'react';
import {NavLink, Route, Switch} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";
import MyNavLink from "./components/MyNavLink/MyNavLink";
import Test from "./pages/Test/Test";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><MyNavLink to="/about" a={1} b={2} c={3}>About</MyNavLink><MyNavLink to="/home">Home</MyNavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Switch><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route><Route path="/home" component={Test}></Route></Switch></div></div></div></div></div>);}
}export default App;
运行结果:

项目结构:

9.解决样式丢失问题
-
public/index.html 中引入样式时不写./写/(常用)
-
public/index.html 中引入样式时不写﹒/写%PUBLIC_URL%(常用)
-
使用HashRouter
1../css/bootstrap.css改为:
<link rel="stylesheet" href="css/bootstrap.css">
2../css/bootstrap.css改为:
<link rel="stylesheet" href="%PUBLIC_URL%/css/bootstrap.css">
3.BroserRouter改成HashRouter
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import {BrowserRouter, HashRouter} from "react-router-dom";const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<HashRouter><App/></HashRouter>
);
10.路由的模糊匹配与严格匹配
- 默认使用的是模糊匹配(简单记:【输入的路径】必须包含要【匹配的路径】,且顺序要一致)
- 开启严格匹配:<Route exact={true} path="/about" component={About}/>
- 严格匹配不要随便开启,需要再开,有些时候开启会导致无法继续匹配二级路由
App.js
import React, {Component} from 'react';
import {Route, Switch} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";
import MyNavLink from "./components/MyNavLink/MyNavLink";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><MyNavLink to="/about">About</MyNavLink><MyNavLink to="/home/a/b">Home</MyNavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Switch><Route exact path="/about" component={About}></Route><Route exact path="/home" component={Home}></Route></Switch></div></div></div></div></div>);}
}export default App;
运行结果:

11.Redirect的使用
- 一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由
- 具体编码:
<Switch> <Route path="/about" component={About}/> <Route path="/home" component={Home}/> <Redirect to="/about"/> </Switch>
App.js
import React, {Component} from 'react';
import {Redirect, Route, Switch} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";
import MyNavLink from "./components/MyNavLink/MyNavLink";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><MyNavLink to="/about">About</MyNavLink><MyNavLink to="/home">Home</MyNavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Switch><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route><Redirect to="/about"></Redirect></Switch></div></div></div></div></div>);}
}export default App;
12.嵌套路由
- 注册子路由时要写上父路由的path值
- 路由的匹配是按照注册路由的顺序进行的
App.js
import React, {Component} from 'react';
import {Redirect, Route, Switch} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";
import MyNavLink from "./components/MyNavLink/MyNavLink";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><MyNavLink to="/about">About</MyNavLink><MyNavLink to="/home">Home</MyNavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Switch><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route><Redirect to="/about"></Redirect></Switch></div></div></div></div></div>);}
}export default App;
Message.jsx
import React, {Component} from 'react';class Message extends Component {render() {return (<div><ul><li><a href="/message1">message001</a> </li><li><a href="/message2">message002</a> </li><li><a href="/message/3">message003</a> </li></ul></div>);}
}export default Message;
News.jsx
import React, {Component} from 'react';class News extends Component {render() {return (<div><ul><li>news001</li><li>news002</li><li>news003</li></ul></div>);}
}export default News;
Home.jsx
import React, {Component} from 'react';
import MyNavLink from "../../components/MyNavLink/MyNavLink";
import {Redirect, Route, Switch} from "react-router-dom";
import News from "./News/News";
import Message from "./Message/Message";class Home extends Component {render() {return (<div><h2>Home组件内容</h2><div><ul className="nav nav-tabs"><li><MyNavLink to="/home/news">News</MyNavLink></li><li><MyNavLink to="/home/message">Message</MyNavLink></li></ul><Switch><Route path="/home/news" component={News}></Route><Route path="/home/message" component={Message}></Route><Redirect to="/home/news"></Redirect></Switch></div></div>);}
}export default Home;
MyNavLink.jsx
import React, {Component} from 'react';
import {NavLink} from "react-router-dom";class MyNavLink extends Component {render() {console.log(this.props)return (<div><NavLink activeClassName="atguigu" className="list-group-item" {...this.props}/></div>);}
}export default MyNavLink;
Header.jsx
import React, {Component} from 'react';class Header extends Component {render() {// console.log('Header组件收到的props是', this.props)return (<div><div className="page-header"><h2>React Router Demo</h2></div></div>);}
}export default Header;
About.jsx
import React, {Component} from 'react';class About extends Component {render() {// console.log('About组件收到的props是', this.props)return (<div><h3>我是About的内容</h3></div>);}
}export default About;
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import {BrowserRouter, HashRouter} from "react-router-dom";const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<HashRouter><App/></HashRouter>
);
项目结构:

运行结果:

13. 向路由组件传递params参数
1.params参数
- 路由链接(携带参数):<Link to='/demo/test/tom/18'}>详情</Link>
- 注册路由(声明接收):<Route path="/demo/test/:name/:age" component={Test}/>
- 接收参数: const {id,title} = this.props.match.params
Header.jsx
import React, {Component} from 'react';class Header extends Component {render() {// console.log('Header组件收到的props是', this.props)return (<div><div className="page-header"><h2>React Router Demo</h2></div></div>);}
}export default Header;
MyNavLink.jsx
import React, {Component} from 'react';
import {NavLink} from "react-router-dom";class MyNavLink extends Component {render() {console.log(this.props)return (<div><NavLink activeClassName="atguigu" className="list-group-item" {...this.props}/></div>);}
}export default MyNavLink;
About.jsx
import React, {Component} from 'react';class About extends Component {render() {// console.log('About组件收到的props是', this.props)return (<div><h3>我是About的内容</h3></div>);}
}export default About;
Detail.jsx
import React, {Component} from 'react';const DetailData = [{id: '01', content: '你好,中国'},{id: '02', content: '你好,尚硅谷'},{id: '03', content: '你好,未来的自己'},
]class Detail extends Component {render() {// console.log(this.props)const {id, title} = this.props.match.paramsconst findResult = DetailData.find((detailObj) => {return detailObj.id === id})return (<ul><li>ID:{id}</li><li>TITLE:{title}</li><li>CONTENT:{findResult.content}</li></ul>);}
}export default Detail;
Message.jsx
import React, {Component} from 'react';
import Detail from "./Detail/Detail";
import {Link, Route} from "react-router-dom";class Message extends Component {state = {messageArr: [{id: '01', title: '消息1'},{id: '02', title: '消息2'},{id: '03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}><Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link></li>)})}</ul><hr></hr><Route path="/home/message/detail/:id/:title" component={Detail}></Route></div>);}
}export default Message;
News.jsx
import React, {Component} from 'react';class News extends Component {render() {return (<div><ul><li>news001</li><li>news002</li><li>news003</li></ul></div>);}
}export default News;
Home.jsx
import React, {Component} from 'react';
import MyNavLink from "../../components/MyNavLink/MyNavLink";
import {Redirect, Route, Switch} from "react-router-dom";
import News from "./News/News";
import Message from "./Message/Message";class Home extends Component {render() {return (<div><h2>Home组件内容</h2><div><ul className="nav nav-tabs"><li><MyNavLink to="/home/news">News</MyNavLink></li><li><MyNavLink to="/home/message">Message</MyNavLink></li></ul><Switch><Route path="/home/news" component={News}></Route><Route path="/home/message" component={Message}></Route><Redirect to="/home/news"></Redirect></Switch></div></div>);}
}export default Home;
App.js
import React, {Component} from 'react';
import {Redirect, Route, Switch} from "react-router-dom";
import About from "./pages/About/About";
import Home from "./pages/Home/Home";
import Header from "./components/Header/Header";
import MyNavLink from "./components/MyNavLink/MyNavLink";class App extends Component {render() {return (<div><div className="row"><div className="col-xs-offset-2 col-xs-8"><Header a={1}></Header></div></div><div className="row"><div className="col-xs-2 col-xs-offset-2"><div className="list-group"><MyNavLink to="/about">About</MyNavLink><MyNavLink to="/home">Home</MyNavLink></div></div><div className="col-xs-6"><div className="panel"><div className="panel-body"><Switch><Route path="/about" component={About}></Route><Route path="/home" component={Home}></Route><Redirect to="/about"></Redirect></Switch></div></div></div></div></div>);}
}export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import {BrowserRouter, HashRouter} from "react-router-dom";const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<HashRouter><App/></HashRouter>
);
运行结果:

项目结构:
14.向路由组件传递search参数
2.search参数
- 路由链接(携带参数): <Link to=' /demo/test?name=tom&age=18'}>详情</Link>
- 注册路由(无需声明,正常注册即可): <Route path="/demo/test" component={Test}/>
- 接收参数: const isearch} = this.props.location
- 备注:获取到的search是urlencoded编码字符串,需要借助querystring解析
Message.jsx
import React, {Component} from 'react';
import Detail from "./Detail/Detail";
import {Link, Route} from "react-router-dom";class Message extends Component {state = {messageArr: [{id: '01', title: '消息1'},{id: '02', title: '消息2'},{id: '03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}>{/*<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>*/}<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link></li>)})}</ul><hr></hr>{/*<Route path="/home/message/detail/:id/:title" component={Detail}></Route>*/}<Route path="/home/message/detail" component={Detail}></Route></div>);}
}export default Message;
Detail.jsx
import React, {Component} from 'react';
import qs from "qs"const DetailData = [{id: '01', content: '你好,中国'},{id: '02', content: '你好,尚硅谷'},{id: '03', content: '你好,未来的自己'},
]class Detail extends Component {render() {console.log(this.props)// const {id, title} = this.props.match.paramsconst {search} = this.props.locationconst {id, title} = qs.parse(search.slice(1))const findResult = DetailData.find((detailObj) => {return detailObj.id === id})return (<ul><li>ID:{id}</li><li>TITLE:{title}</li><li>CONTENT:{findResult.content}</li></ul>);}
}export default Detail;
运行结果:

项目结构:

15.向路由组件传递state参数
state参数:
- 路由链接(携带参数): <Link to={{path:' /demo/test',state:{name : ' tom' ,age:18]}}>详情</Link>注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
- 接收参数: this.props.location.state
- 备注:刷新也可以保留住参数
Message.jsx
import React, {Component} from 'react';
import Detail from "./Detail/Detail";
import {Link, Route} from "react-router-dom";class Message extends Component {state = {messageArr: [{id: '01', title: '消息1'},{id: '02', title: '消息2'},{id: '03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}>{/*<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>*/}{/*<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>*/}<Link to={{pathname: '/home/message/detail',state: {id: msgObj.id, title: msgObj.title}}}>{msgObj.title}</Link></li>)})}</ul><hr></hr>{/*<Route path="/home/message/detail/:id/:title" component={Detail}></Route>*/}{/*<Route path="/home/message/detail" component={Detail}></Route>*/}<Route path="/home/message/detail" component={Detail}></Route></div>);}
}export default Message;
Detail.jsx
import React, {Component} from 'react';
import qs from "qs"const DetailData = [{id: '01', content: '你好,中国'},{id: '02', content: '你好,尚硅谷'},{id: '03', content: '你好,未来的自己'},
]class Detail extends Component {render() {console.log(this.props)// const {id, title} = this.props.match.params// const {search} = this.props.location// const {id, title} = qs.parse(search.slice(1))const {id, title} = this.props.location.state || {}const findResult = DetailData.find((detailObj) => {return detailObj.id === id}) || {}return (<ul><li>ID:{id}</li><li>TITLE:{title}</li><li>CONTENT:{findResult.content}</li></ul>);}
}export default Detail;
运行结果:

16.总结路由参数

17.push与repalce
Message.jsx
import React, {Component} from 'react';
import Detail from "./Detail/Detail";
import {Link, Route} from "react-router-dom";class Message extends Component {state = {messageArr: [{id: '01', title: '消息1'},{id: '02', title: '消息2'},{id: '03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}>{/*<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>*/}{/*<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>*/}<Link replace={true} to={{pathname: '/home/message/detail',state: {id: msgObj.id, title: msgObj.title}}}>{msgObj.title}</Link></li>)})}</ul><hr></hr>{/*<Route path="/home/message/detail/:id/:title" component={Detail}></Route>*/}{/*<Route path="/home/message/detail" component={Detail}></Route>*/}<Route path="/home/message/detail" component={Detail}></Route></div>);}
}export default Message;
- push:留下记录
- repalce:不留记录
18.编程式路由导航
Message.jsx
import React, {Component} from 'react';
import Detail from "./Detail/Detail";
import {Link, Route} from "react-router-dom";class Message extends Component {state = {messageArr: [{id: '01', title: '消息1'},{id: '02', title: '消息2'},{id: '03', title: '消息3'},]}render() {const {messageArr} = this.statereturn (<div><ul>{messageArr.map((msgObj) => {return (<li key={msgObj.id}>{/*<Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>*/}{/*<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>*/}<Link replace={true} to={{pathname: '/home/message/detail',state: {id: msgObj.id, title: msgObj.title}}}>{msgObj.title}</Link></li>)})}</ul><hr></hr>{/*<Route path="/home/message/detail/:id/:title" component={Detail}></Route>*/}{/*<Route path="/home/message/detail" component={Detail}></Route>*/}<Route path="/home/message/detail" component={Detail}></Route></div>);}
}export default Message;
Detail.jsx
import React, {Component} from 'react';
import qs from "qs"const DetailData = [{id: '01', content: '你好,中国'},{id: '02', content: '你好,尚硅谷'},{id: '03', content: '你好,未来的自己'},
]class Detail extends Component {render() {console.log(this.props)// const {id, title} = this.props.match.params// const {search} = this.props.location// const {id, title} = qs.parse(search.slice(1))const {id, title} = this.props.location.state || {}const findResult = DetailData.find((detailObj) => {return detailObj.id === id}) || {}return (<ul><li>ID:{id}</li><li>TITLE:{title}</li><li>CONTENT:{findResult.content}</li></ul>);}
}export default Detail;
19.withRouter的作用
News.jsx
import React, {Component} from 'react';class News extends Component {componentDidMount() {setTimeout(() => {this.props.history.push('/home/message')}, 2000)}render() {return (<div><ul><li>news001</li><li>news002</li><li>news003</li></ul></div>);}
}export default News;
- 借助this.prosp.history对象上的API对操作路由跳转、前进、后退
- this.prosp.history.push()
- this.prosp.history.replace()
- this.prosp.history.goBack()
- this.prosp.history.goForward()
- this.prosp.history.go()
- withRouter可以加工一般组件,让一般组件具备路由组件所特有的API
- withRouter的返回值是一个新组件
Header.jsx
import React, {Component} from 'react';
import {withRouter} from "react-router-dom";class Header extends Component {back = () => {this.props.history.goBack()}forward = () => {this.props.history.goForward()}go = () => {this.props.history.go(2)}render() {// console.log('Header组件收到的props是', this.props)return (<div><div className="page-header"><h2>React Router Demo</h2><button onClick={this.back}>回退</button><button onClick={this.forward}>前进</button><button onClick={this.go}>go</button></div></div>);}
}export default withRouter(Header);
20.BrowserRouter与HashRouter
- 1.底层原理不一样:
- BrowserRouter使用的是H5的history API,不兼容IE9及以下版本。
- HashRouter使用的是URL的哈希值
- 2.path表现形式不一样
- BrowserRouter的路径中没有#,例如: localhost:3000/demo/test
- HashRouter的路径包含#,例如: localhost:3000/#/demo/test
- 3.刷新后对路由state参数的影响
- (1).BrowserRouter没有任何影响,因为state保存在history对象中。
- (2).HashRouter刷新后会导致路由state参数的丢失。
- 4.备注: HashRouter可以用于解决一些路径错误相关的问题。
相关文章:
[尚硅谷React笔记]——第5章 React 路由
目录: 对SPA应用的理解对路由的理解前端路由原理路由的基本使用路由组件与一般组件NavLink的使用封装NavLink组件Switch的使用解决样式丢失问题路由的模糊匹配与严格匹配Redirect的使用嵌套路由向路由组件传递params参数向路由组件传递search参数.向路由组件传递st…...
如何去掉不够优雅的IF-ELSE
不够优雅的IF-ELSE: 在一个方法中根据两个参数的不同值组合来返回四种可能的类型,你可以使用条件语句,例如 if-else 语句或 switch 语句,来实现这个逻辑。以下是一个示例,假设你有两个参数 param1 和 param2ÿ…...
Python中defaultdict的使用
文章目录 Python 中的 defaultdict 与 dictPython 中的 defaultdict Python 中 defaultdict 的有用函数Python 中的 defaultdict.clear()Python 中的 defaultdict.copy()Python 中的 defaultdict.default_factory()Python 中的 defaultdict.get(key, default value) 今天的文章…...
【ccc3.8】虚拟列表
一个简单的虚拟列表,没有任何其他东西。 原理就是向上滚动时,将下面离开屏幕的那一个item塞到上侧来: 主代码仅有两个:ScrollList对应的滚动容器,ScrollListItem对应单项的预制体 当前支持两种:竖向滚动、…...
【23种设计模式】单一职责原则
个人主页:金鳞踏雨 个人简介:大家好,我是金鳞,一个初出茅庐的Java小白 目前状况:22届普通本科毕业生,几经波折了,现在任职于一家国内大型知名日化公司,从事Java开发工作 我的博客&am…...
DNS入门学习:什么是TTL值?如何设置合适的TTL值?
TTL值是域名解析中的一个重要参数,TTL值设置的合理与否对于域名解析的效率和准确性有着非常重要的影响,因此对于网站管理者而言,了解什么是TTL值以及如何设置合理的TTL值对于做好域名解析管理,确保网站的安全稳定运行至关重要。 …...
ilr normalize isometric log-ratio transformation
visium_heart/st_snRNAseq/05_colocalization/create_niches_ct.R at 5b30c7e497e06688a8448afd8d069d2fa70ebcd2 saezlab/visium_heart (github.com) 更多内容,关注微信:生信小博士 The ILR (Isometric Log-Ratio) transformation is used in the anal…...
el表单的简单查询方法
预期效果 实现表单页面根据groupid 、type 、errortype进行数据过滤 实现 第一步,在页面中添加输入或者是下拉框,并且用相应的v-model进行绑定 <div style"display: flex;flex-direction: row;"><el-input style"width: auto…...
【USRP】通信总的分支有哪些
概述 通信是一个广泛的领域,涵盖了许多不同的技术、应用和专业分支。以下是通信领域的一些主要分支: 有线通信:这涉及到利用物理媒介(如电缆、光纤)进行通信。 电信:包括电话、电报和传真服务。宽带&#…...
关于服务器网络代理解决方案(1024)
方法一、nginx代理 配置代理服务器 在能够访问外网的服务器上,安装和配置 Nginx。你可以使用包管理器来安装 Nginx,例如: csharpCopy codesudo apt-get install nginx # 对于基于 Debian/Ubuntu 的系统 sudo yum install nginx # 对于基于 C…...
Linux下 /etc/shadow内容详解
/etc/shadow 文件,用于存储 Linux 系统中用户的密码信息,又称为“影子文件”。 前面介绍了 /etc/passwd 文件,由于该文件允许所有用户读取,易导致用户密码泄露,因此 Linux 系统将用户的密码信息从 /etc/passwd 文件中…...
Go学习第二章——变量与数据类型
Go变量与数据类型 1 变量1.1 变量概念1.2 变量的使用步骤1.3 变量的注意事项1.4 ""的使用 2 数据类型介绍3 整数类型3.1 有符号整数类型3.2 无符号整数类型3.3 其他整数类型3.4 整型的使用细节 4 小数类型/浮点型4.1 浮点型的分类4.2 简单使用 5 字符类型5.1 字符类型…...
【剑指Offer】:循环有序列表的插入(涉及链表的知识)
给定循环单调非递减列表中的一个点,写一个函数向这个列表中插入一个新元素 insertVal ,使这个列表仍然是循环升序的 给定的可以是这个列表中任意一个顶点的指针,并不一定是这个列表中最小元素的指针 如果有多个满足条件的插入位置,…...
【Django 04】Django-DRF(ModelViewSet)
DRF是什么? ModelViewSet 是 Django REST framework 提供的一个视图集类,它封装了常见的模型操作方法。 模型类提供了默认的增删改查功能。 它继承自 GenericViewSet、ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、Dest…...
ubuntu命令
一、 防火墙命令 1、安装防火墙 sudo sudo apt-get install ufw2、查看防火墙状态 sudo ufw status# 返回结果 # Status: inactive # 表示没有开启防火墙3、开启防火墙 sudo ufw enable# 返回结果 # Command may disrupt existing ssh connections. Proceed with operation…...
C++学习之强制类型转换
强制类型转换运算符 带着三个疑问阅读: 出现的背景是什么?何时使用?如何使用? MSDN . 强制转换运算符 C中的四种强制类型转换符详解 static_cast (1) 使用场景 在基本数据类型之间转换,如把 int 转换为 char&#…...
在Linux中,可以使用以下命令来查看进程
在Linux中,可以使用以下命令来查看进程: ps 命令:显示当前用户的进程状态。 ps:显示当前终端会话中正在运行的进程。ps aux:显示系统中所有正在运行的进程,包括其他用户的进程。ps -ef:显示系统…...
【算法训练-动态规划 一】【应用DP问题】零钱兑换、爬楼梯、买卖股票的最佳时机I、打家劫舍
废话不多说,喊一句号子鼓励自己:程序员永不失业,程序员走向架构!本篇Blog的主题是【动态规划】,使用【数组】这个基本的数据结构来实现,这个高频题的站点是:CodeTop,筛选条件为&…...
2023年中职组“网络安全”赛项云南省竞赛任务书
2023年中职组“网络安全”赛项 云南省竞赛任务书 一、竞赛时间 总计:360分钟 竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 A模块 A-1 登录安全加固 180分钟 200分 A-2 本地安全策略配置 A-3 流量完整性保护 A-4 事件监控 A-5 服务加固…...
Modeling Deep Learning Accelerator Enabled GPUs
Modeling Deep Learning Accelerator Enabled GPUs 发表在 ISPASS 2019 上。文章研究了 NVIDIA 的 Volta 和 Turing 架构中张量核的设计,并提出了 Volta 中张量核的架构模型。 基于 GPGPU-Sim 实现该模型,并且支持 CUTLASS 运行。发现其性能与硬件非常吻…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
云计算——弹性云计算器(ECS)
弹性云服务器:ECS 概述 云计算重构了ICT系统,云计算平台厂商推出使得厂家能够主要关注应用管理而非平台管理的云平台,包含如下主要概念。 ECS(Elastic Cloud Server):即弹性云服务器,是云计算…...
shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
《Playwright:微软的自动化测试工具详解》
Playwright 简介:声明内容来自网络,将内容拼接整理出来的文档 Playwright 是微软开发的自动化测试工具,支持 Chrome、Firefox、Safari 等主流浏览器,提供多语言 API(Python、JavaScript、Java、.NET)。它的特点包括&a…...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...
Xen Server服务器释放磁盘空间
disk.sh #!/bin/bashcd /run/sr-mount/e54f0646-ae11-0457-b64f-eba4673b824c # 全部虚拟机物理磁盘文件存储 a$(ls -l | awk {print $NF} | cut -d. -f1) # 使用中的虚拟机物理磁盘文件 b$(xe vm-disk-list --multiple | grep uuid | awk {print $NF})printf "%s\n"…...
SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题
分区配置 (ptab.json) img 属性介绍: img 属性指定分区存放的 image 名称,指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件,则以 proj_name:binary_name 格式指定文件名, proj_name 为工程 名&…...
springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
HTML前端开发:JavaScript 获取元素方法详解
作为前端开发者,高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法,分为两大系列: 一、getElementBy... 系列 传统方法,直接通过 DOM 接口访问,返回动态集合(元素变化会实时更新)。…...
