还是先用脚手架生成一个app,删除多余的代码,只留一个index.js
安装react-router-dom:
npm install --save react-router-dom
老套路,先编写一个简单的路由程序先跑起来:
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
function Index() {
return <h2>JSPang.com</h2>;
}
function List() {
return <h2>List-Page</h2>;
}
function AppRouter() {
return (
<Router>
<ul>
<li> <Link to="/">首页</Link> </li>
<li><Link to="/list/">列表</Link> </li>
</ul>
<Route path="/" exact component={Index} />
<Route path="/list/" component={List} />
</Router>
);
}
export default AppRouter;
这里的两个组件用function的方式写,实际工作中要写在另一个文件夹里:
编写index:
import React, { Component } from 'react';
class Index extends Component {
constructor(props) {
super(props);
this.state = { }
}
render() {
return ( <h2>JSPang.com</h2> );
}
}
export default Index;
编写list:
import React, { Component } from 'react';
class List extends Component {
constructor(props) {
super(props);
this.state = { }
}
render() {
return ( <h2>List Page</h2> );
}
}
export default List;
在主页面里引入即可:
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Index from './Pages/Index'
import List from './Pages/List'
function AppRouter() {
return (
<Router>
<ul>
<li> <Link to="/">首页</Link> </li>
<li><Link to="/list/">列表</Link> </li>
</ul>
<Route path="/" exact component={Index} />
<Route path="/list/" component={List} />
</Router>
);
}
export default AppRouter;
exact:就是精准匹配的意思,就是表面的意思,必须完全相同才能匹配出路径
route里的动态传值是允许的,:开始,紧接着要传的值即可:
<li><Link to="/list/123">列表</Link> </li>
在list组件上接收并显示传递值:挂载组件后用this.props.match接收传来的值。
import React, { Component } from 'react';
class List extends Component {
constructor(props) {
super(props);
this.state = { }
}
render() {
return ( <h2>List Page</h2> );
}
//-关键代码---------start
componentDidMount(){
console.log(this.props.match)
}
//-关键艾玛---------end
}
export default List;
console.log(this.props.match)控制台打印出的这个对象,有三个部分的值
- patch:自己定义的路由规则,可以清楚的看到是可以产地id参数的。
- url: 真实的访问路径,这上面可以清楚的看到传递过来的参数是什么。
- params:传递过来的参数,
key
和value
值
那接收主页面传来的id,按如下代码接收:
import React, { Component } from 'react';
class List extends Component {
constructor(props) {
super(props);
this.state = { }
}
render() {
return ( <h2>List Page->{this.state.id}</h2> );
}
componentDidMount(){
// console.log(this.props.match.params.id)
let tempId=this.props.match.params.id
this.setState({id:tempId })
}
}
export default List;
写一个列表数组,模拟从后台读取数据:
constructor(props) {
super(props);
this.state = {
list:[
{uid:123,title:'技术胖的个人博客-1'},
{uid:456,title:'技术胖的个人博客-2'},
{uid:789,title:'技术胖的个人博客-3'},
]
}
}
在列表组件里进行有效的遍历:
render() {
return (
<ul>
{
this.state.list.map((item,index)=>{
return (
<li key={index}> {item.title} </li>
)
})
}
</ul>
)
}
把link to里的内容解析成js形式,如下:
render() {
return (
<ul>
{
this.state.list.map((item,index)=>{
return (
<li key={index}>
<Link to={'/list/'+item.uid}> {item.title}</Link>
</li>
)
})
}
</ul>
)
}
全部代码:
import React, { Component } from 'react';
import { Link } from "react-router-dom";
class Index extends Component {
constructor(props) {
super(props);
this.state = {
list:[
{uid:123,title:'技术胖的个人博客-1'},
{uid:456,title:'技术胖的个人博客-2'},
{uid:789,title:'技术胖的个人博客-3'},
]
}
}
render() {
return (
<ul>
{
this.state.list.map((item,index)=>{
return (
<li key={index}>
<Link to={'/list/'+item.uid}> {item.title}</Link>
</li>
)
})
}
</ul>
)
}
}
export default Index;
关于ReactRouter的重定向:Redirect分两种
- 标签式重定向:就是利用
<Redirect>
标签来进行重定向,业务逻辑不复杂时建议使用这种。 - 编程式重定向:这种是利用编程的方式,一般用于业务逻辑当中,比如登录成功跳转到会员中心页面
跳转和重定向的区别:重定向是不可以按浏览器回退按钮的,而跳转可以。
重点,二级导航video组件的编写:link链接与对应的组件。
import React from "react";
import { Route, Link } from "react-router-dom";
import Reactpage from './video/ReactPage'
import Vue from './video/Vue'
import Flutter from './video/Flutter'
function Video(){
return (
<div>
<div className="topNav">
<ul>
<li><Link to="/video/reactpage">React教程</Link></li>
<li><Link to="/video/vue">Vue教程</Link></li>
<li><Link to="/video/flutter">Flutter教程</Link></li>
</ul>
</div>
<div className="videoContent">
<div><h3>视频教程</h3></div>
<Route path="/video/reactpage/" component={Reactpage} />
<Route path="/video/vue/" component={Vue} />
<Route path="/video/flutter/" component={Flutter} />
</div>
</div>
)
}
export default Video;
写完以上的,再在AppRouter.js(入口文件)里引入该组件:
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Index from './Pages/Index'
//--关键代码------------start
import Video from './Pages/Video'
//--关键代码------------end
import './index.css'
function AppRouter() {
return (
<Router>
<div className="mainDiv">
<div className="leftNav">
<h3>一级导航</h3>
<ul>
<li> <Link to="/">博客首页</Link> </li>
{/*--关键代码------------start*/}
<li><Link to="/video/">视频教程</Link> </li>
{/*--关键代码------------end*/}
<li><Link to="">职场技能</Link> </li>
</ul>
</div>
<div className="rightMain">
<Route path="/" exact component={Index} />
{/*--关键代码------------start*/}
<Route path="/video/" component={Video} />
{/*--关键代码------------end*/}
</div>
</div>
</Router>
);
}
export default AppRouter;
动态路由的实现无非是:后台读取数据,把原来写死的改为变量的形式。
举个栗子:
import React from "react";
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import Index from './Pages/Index'
import Video from './Pages/Video'
import Workplace from './Pages/Workplace'
import './index.css'
function AppRouter() {
let routeConfig =[
{path:'/',title:'博客首页',exact:true,component:Index},
{path:'/video/',title:'视频教程',exact:false,component:Video},
{path:'/workplace/',title:'职场技能',exact:false,component:Workplace}
]
return (
<Router>
<div className="mainDiv">
<div className="leftNav">
<h3>一级导航</h3>
<ul>
{
routeConfig.map((item,index)=>{
return (<li key={index}> <Link to={item.path}>{item.title}</Link> </li>)
})
}
</ul>
</div>
<div className="rightMain">
{
routeConfig.map((item,index)=>{
return (<Route key={index} exact={item.exact} path={item.path} component={item.component} />)
})
}
</div>
</div>
</Router>
);
}
export default AppRouter;
嘿嘿,这里的路由入门就先到这里了。接下来搞大名鼎鼎的hook。