在最后有一个小项目,里面用到的知识点都在前面,最后附上了项目地址
Web分类
前端渲染
是当客户端第一次访问网站的时候,就将该网站的所有数据全部传给客户端,当网站不同页面跳转的时候,并不需要再向后端发送请求
后端渲染
则是一个网站的不同页面的切换都要向后端发送请求重新渲染
当一个网站的不同页面跳转的时候是相同的url,就是前端渲染的,使用Route也是前端渲染,但是会给每一个页面都唯一对应一个url,因为网站和应用不一样,很多应用可能需要某个功能的时候一层层点进去,但是网页可以直接通过某个链接直接进入到特定页面。
安装环境
VSCODE安装插件:Auto Import - ES6, TS, JSX, TSX
安装Route组件:npm i react-router-dom
Route组件介绍
URL中传递参数
解析URL:
<Route path="/linux/:chapter_id/:section_id/" element={<Linux />} />
获取参数,类组件写法:
import React, { Component } from 'react';
import { useParams } from 'react-router-dom';
class Linux extends Component {
state = { }
render() {
console.log(this.props.params);
return <h1>Linux</h1>;
}
}
export default (props) => (
<Linux
{...props}
params={useParams()}
/>
)
```函数组件写法:
```js
import React, { Component } from 'react';
import { useParams } from 'react-router-dom';
const Linux = () => {
console.log(useParams());
return (<h1>Linux</h1>);
}
export default Linux;
Search Params传递参数
类组件写法:
import React, { Component } from 'react';
import { useSearchParams } from 'react-router-dom';
class Django extends Component {
state = {
searchParams: this.props.params[0], // 获取某个参数
setSearchParams: this.props.params[1], // 设置链接中的参数,然后重新渲染当前页面
}
handleClick = () => {
this.state.setSearchParams({
name: "abc",
age: 20,
})
}
render() {
console.log(this.state.searchParams.get('age'));
return <h1 onClick={this.handleClick}>Django</h1>;
}
}
export default (props) => (
<Django
{...props}
params={useSearchParams()}
/>
);
函数组件写法:
import React, { Component } from 'react';
import { useSearchParams } from 'react-router-dom';
const Django = () => {
let [searchParams, setSearchParams] = useSearchParams();
console.log(searchParams.get('age'));
return (<h1>Django</h1>);
}
export default Django;
重定向
使用Navigate组件可以重定向。
<Route path="*" element={ <Navigate replace to="/404" /> } />
嵌套路由
<Route path="/web" element={<Web />}>
<Route index path="a" element={<h1>a</h1>} />
<Route index path="b" element={<h1>b</h1>} />
<Route index path="c" element={<h1>c</h1>} />
</Route>
注意:需要在父组件中添加组件,用来填充子组件的内容。
index.js
root.render(
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
navbar.js
class NavBar extends Component {
state = { }
render() {
return (
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<div class="container-fluid">
<a class="navbar-brand" href="/">讲义</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-link active" aria-current="page" href="/">Home</a>
<a class="nav-link" href="/linux">Linux</a>
<a class="nav-link" href="/django">Django</a>
<a class="nav-link" href="/web">Web</a>
</div>
</div>
</div>
</nav>
);
}
}
app.js
class App extends Component {
state = { }
render() {
return (
<React.Fragment>
<NavBar />
</React.Fragment>
);
}
}
初始页面实现如下:
接下来,将Home Linux Django Web都做成一个组件
class App extends Component {
state = { }
render() {
return (
<React.Fragment>
<NavBar />
<div className='container'>
<Routes>
<Route path="/" element={<Home />}/>
<Route path="/linux" element={<Linux />}/>
<Route path="/django" element={<Django />}/>
<Route path="/web" element={<Web />}/>
</Routes>
</div>
</React.Fragment>
);
}
}
navbar.jsx
class NavBar extends Component {
state = { }
render() {
return (
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<div className="container-fluid">
<Link className="navbar-brand" to="/">讲义</Link>
<button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNavAltMarkup">
<div className="navbar-nav">
<Link className="nav-link active" to="/">Home</Link>
<Link className="nav-link" to="/linux">Linux</Link>
<Link className="nav-link" to="/django">Django</Link>
<Link className="nav-link" to="/web">Web</Link>
</div>
</div>
</div>
</nav>
);
}
}
实现web页面
web.jsx
class Web extends Component {
state = {
webs : [
{id: 0, title: 'HTML'},
{id: 1, title: 'CSS'},
{id: 2, title: 'JavaScript'},
{id: 3, title: '拳皇'},
{id: 4, title: 'React'},
]
}
render() {
return (
<React.Fragment>
<h1>Web</h1>
<hr />
<div>
{this.state.webs.map(web => (
<div key={web.id}>
<Link to={`/web/content/${web.id}`}>{web.id +"."+web.title}</Link>
</div>
))}
</div>
</React.Fragment>
);
}
}
已经有了连接,接下来要通过每个url里面的id去渲染对应的页面,因为一个网页可能有上万个目录,不可能写这么多路由,所以一般url最后的id会变成一个变量,所以要在URL里传递参数
第一种,通过URL传递参数
webContent.jsx
class WebContent extends Component {
state = { }
render() {
<React.Fragment>
<h1>Web - {this.props.params.chapter}</h1>
<hr />
<p>内容</p>
<Link to="/web">返回</Link>
</React.Fragment>
}
}
export default (props) => (
<WebContent
{...props}
params={useParams()}
/>
)
app.jsx
<Route path="/web/content/:chapter/" element={<WebContent />}/>
第二种:通过search Params传递参数
web.jsx
<Link to={`/web/content?chapter=${web.id}`}>{web.id +"."+web.title}</Link>
app.jsx
<Route path="/web/content" element={<WebContent />}/>
webContent.jsx
class WebContent extends Component {
state = {
searchParams : this.props.params[0],
setSearchParams : this.props.params[1],
};
render() {
return (
<React.Fragment>
<h1>Web - {this.state.searchParams.get('chapter')}</h1>
<hr />
<p>内容</p>
<Link to="/web">返回</Link>
</React.Fragment>
);
}
}
export default (props) => (
<WebContent
{...props}
params={useSearchParams()}
/>
)
当一个页面不存在的时候,重定向到404
app.jsx
<Route path="/404" element={<NotFound />} />
<Route path="*" element={ <Navigate replace to="/404" /> } />
有时候可能一个页面里面有很多子页面,上半部分是不变的,但是下半部分会通过不同的路由显示不同的内容,这个时候就用到了嵌套路由
比如Linux页面有两个嵌套路由homework和terminal
app.js
<Route path="/linux" element={<Linux />}>
<Route path="homework" element={<h4>homework的内容</h4>}></Route>
<Route path="terminal" element={<h4>terminal的内容</h4>}></Route>
</Route>
linux.js
render() {
return (
<React.Fragment>
<h1>Linux</h1>
<hr/>
<Outlet />
</React.Fragment>
);
}
学习网站ACwing
项目地址:GitCode