【共享单车】—— React后台管理系统开发手记:Router 4.0路由实战演练
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录。最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star。
一、React Router 4.0核心概念
4.0版本中已不需要路由配置,一切皆组件
- react-router:基础路由包
- 提供了一些router的核心api,包括Router,Route,Switch等
- react-router-dom:基于浏览器的路由(包含react-router)
- 提供了BrowerRouter,HashRouter,Route,Link,NavLink
- 安装:
npm install react-router-dom --save
//或
yarn add react-router-dom
react-router-dom核心用法
- HashRouter和BrowserRouter区别
- HashRouter
http://localhost:3000/#/admin/buttons
- BrowserRouter
http://localhost:3000/admin/buttons
- Route用法
- path属性:路由地址
- component属性:路由对应要跳转到的组件
- exact属性:代表精准匹配,必须path完全匹配才可以加载对应组件
- render方法:渲染一个组件,其中包裹一个子路由
<Route path="/admin/ui/buttons" component={Button} /><Route path="/admin" render={() => <Admin>
<Route path="/admin/home" component={Home} />
</Admin>
}/>
- 导航
- NavLink:菜单里的导航;Link:超链接导航
- to:可以传一个字符串,也可以传一个location对象
import {Link} from 'react-router-dom'; const Header=()=>{
<header>
<nav>
<li><Link to='/'>Home</Link></li>
<li><Link to='/about'>About</Link></li>
<li><Link to='/three'>Three</Link></li>
</nav>
</header>
}<Link to={{pathname:'/three/7'}}>Three #7</Link> 定义:<Route path="/three/:number" />
取值:this.props.match.params.number
一个基本的location对象: { pathname: '/', search:'', hash:'', key:'abc123', state:{} }
Switch 选择
选择符合要求的Route,自上至下找到一个可以匹配的内容则不继续加载其他
- <Switch>是唯一的因为它仅仅只会渲染一个路径
<Switch>
<Route path='/admin/ui/buttons' component={Buttons}/>
<Route path='/admin/ui/models' component={Models}/>
<Route path='/admin/ui/loading' component={Loading}/>
</Switch>
Redirect 重定向
<Redirect to="/admin/home">
二、React Router4.0 Demo介绍
|
|
|
| 嵌套路由 | 动态路由 |
混合组件化 -- 将Route和Link放到同一个页面
- HashRouter将Link和Router进行包裹,其内部必须只能有一个子节点
- 渲染对应component中的组件
- 通过Link组件的to属性设置路由地址
- 通过Route组件的path属性匹配路由地址
- 注意:Route添加exact属性可以做到【路径精准匹配】,否则
/about既可以匹配/也可以匹配/about等路由地址
Demo代码
- Home.js:显示整个页面内容
import React from 'react';
import {HashRouter,Route,Link,Switch} from 'react-router-dom'
import Main from './Main';
import About from './About';
import Topics from './Topics'; class Home extends React.Component{
render(){
return(
<HashRouter>
<div>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<hr></hr>
<Switch>
<Route path="/" exact={true} component={Main}></Route>
<Route path="/about" component={About}></Route>
<Route path="/topics" component={Topics}></Route>
</Switch>
</div>
</HashRouter>
);
}
}
export default Home;Main.js :路由组件 (其它组件同Main.js)
import React,{Component} from 'react';
class Main extends Component{
render(){
return(
<div>
this is Main.
</div>
);
}
}
export default Main;index.js:将Home组件挂载到根节点上
import Home from './pages/router_demo/Home' ReactDOM.render(<Home />, document.getElementById('root'));
配置化 -- 将Route路由提取到一个单独的JS文件中
- Router、Link和Route
- Router是节点 ——下面只能包含一个盒子标签,如这里的div,内容为路由及路由组件
<Router>
<div>
//otherCoding
</div>
</Router> - Link是链接 —— 在html界面中会解析成a标签,to代表链接地址(一个相对路径 )
<Router>
<div>
<ul>
<li><link to='/'>首页</Link></li>
<li><link to='/other'>其他页</Link></li>
</ul>
</div>
</Router> Route是路由组件 —— path代表路径,component代表路径所对应的界面
<Router>
<div>
<ul>
<li><Link to="/home">首页</Link></li>
<li><Link to="/other">其他页</Link></li>
</ul>
<Route path="/home" component={Home}/>
<Route path="/other" component={Other}/>
</div>
</Router>
配置化实现路由功能
- router.js:根据Home.js中的Link导航配置找到对应的组件
import React from 'react'
import {HashRouter as Router,Route} from 'react-router-dom'
import Main from './Main';
import About from './About';
import Topics from './Topics';
import Home from './Home' export default class IRouter extends React.Component{ render(){
return (
<Router>
<Home>
{/*根据导航配置找到对应的组件*/}
<Route path="/" exact={true} component={Main}></Route>
<Route path="/about" component={About}></Route>
<Route path="/topics" component={Topics}></Route>
</Home>
</Router>
)
}
} Home.js:①页面中配置Link导航 ②在router.js中通过Route找到组件 ③呈现在{this.props.children}处
import React from 'react';
import {Link} from 'react-router-dom' class Home extends React.Component{
render(){
return(
<div>
{/*页面导航的配置*/}
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
<li>
<Link to="/topics">Topics</Link>
</li>
</ul>
<hr />
{/*找到路由匹配的组件后呈现的位置*/}
{this.props.children}
</div>
);
}
}
export default Home;- index.js:将router组件挂载到根节点上
import Router from './pages/router_demo/router' ReactDOM.render(<Router />, document.getElementById('root'));
嵌套路由
router.js:使用render方法渲染Main主页面极其嵌套路由;注意箭头函数后不能加{},否则只执行,并不会返回(return)
import User from './User'; {/*改变Main路由,添加render方法*/}
<Route path="/main" render={() =>
<Main>
<Route path="/main/user" component={User}></Route>
</Main>
}></Route>Main.js:使用Link配置子路由导航,同时设置子路由显示的位置{this.props.children}
import {Link} from 'react-router-dom' {/*添加Link配置子路由导航*/}
<Link to='/main/user'>嵌套路由</Link>
<hr />
{this.props.children}- 坑:因为前面main组件的路由添加了exact={true}精确匹配,会导致/user不被匹配,无法获取子路由
- 解决:去掉exact属性,使用/main匹配main组件路由,/main/user匹配user子组件路由
- 获取动态路由的值
- Main.js:设置跳转的路由链接
<Link to='/main/test-id'>动态路由1</Link>
<br />
<Link to='/main/456'>动态路由2</Link> router.js:添加动态路由,即
path:"/main/:value"用冒号定义的路由内容import Info from './Info'; {/*用冒号定义路由内容*/}
<Route path="/main" render={() =>
<Main>
<Route path="/main/:value" component={Info}></Route>
</Main>
}></Route>- Info.js:获取定义的动态路由内容信息,通过
{this.props.match.params.路由的名称}import React,{Component} from 'react';
class Info extends Component{
render(){
return(
<div>
这里是测试动态路由功能
动态路由的值时:{this.props.match.params.value}
</div>
);
}
}
export default Info;
匹配路由的404页面
router.js:添加没有path属性的Route组件放置Switch组件内部的最后位置,作为默认路由
import {HashRouter as Router,Route,Switch} from 'react-router-dom'
import NoMatch from './NoMatch' <Switch>
{/*Switch组件从上到下,只匹配一个路由*/}
<Route path="/main" render={() =>
<Main>
<Route path="/main/:value" component={Info}></Route>
</Main>
}></Route>
<Route path="/about" component={About}></Route>
<Route path="/topics" component={Topics}></Route>
<Route component={NoMatch}></Route>
</Switch>NoMatch.js
import React from 'react';
class NoMatch extends React.Component{
render(){
return(
<div>
404 Not Found
</div>
);
}
}
export default NoMatch;
三、项目路由实战开发
- index.js:挂载Router组件到根节点
// import Admin from './admin'
import Router from './router' ReactDOM.render(<Router />, document.getElementById('root')); App.js:项目路由入口文件
- 用户访问项目时输入url对应的作为整个文件输出,一共有三种情况:登录、详情页、首页
- App.js内部什么都没有,只有{this.props.children},主要用来存放子组件(即上述三个页面),否则没有显示位置
/**路由入口组件 */ import React, { Component } from 'react';
import './App.css'; class App extends Component {
render() {
return (
<div>
{this.props.children}
</div>
);
}
} export default App; 总结:想利用Route显示组件信息,则必须有调动
{this.props.children}显示其页面的组件
src->router.js:有三个页面就需要有三个路由
path为/login渲染登录组件
- path为/admin渲染首页:①用render函数返回子路由Admin组件 ②定义嵌套路由/admin/ui/buttons显示组件按钮 ③无path显示404页面 ④外层用Switch包裹保证只显示其中第一个匹配的Route
path为/order/detail渲染详情页
import React from 'react'
import {HashRouter, Route, Switch} from 'react-router-dom'
import App from './App'
import Login from './pages/Login'
import NoMatch from './pages/NoMatch'
import Admin from './admin'
import Buttons from './pages/ui/buttons' export default class IRouter extends React.Component{ render() {
return (
<HashRouter>
<App>
<Route path="/login" component={Login}></Route>
<Route path="/admin" render={() =>
<Admin>
<Switch>
<Route path="/admin/ui/buttons" component={Buttons}></Route>
<Route component={NoMatch}></Route>
</Switch>
</Admin>
}></Route>
<Route path="/order/detail" component={Login}></Route>
</App>
</HashRouter>
)
}
}
- src->admin.js:content部分使用
{this.props.children}显示在router.js中Route得到的页面<Row className="content">
{/* <Home /> */}
{this.props.children}
</Row> - NevLeft->index.js:通过左侧导航栏进行跳转
- 有Route就一定要有Link指定路由地址
- 利用react-router-dom的NavLink设置路由地址,NavLink组件显示的内容为
{item.title},to跳转的地址为{item.key}import {NavLink} from 'react-router-dom' return <Menu.Item title={item.title} key={item.key}>
<NavLink to={item.key}>{item.title}</NavLink>
</Menu.Item>
pages->ui->button.js:匹配的是
/admin/ui/buttons则将Button组件渲染到Admin组件的content中import React,{Component} from 'react';
class Buttons extends Component{
render(){
return(
<div>
this is Buttons.
</div>
);
}
}
export default Buttons;pages->NoMatch->index.js:没有对应的路由匹配则将404页面渲染到Admin组件的content中
import React,{Component} from 'react';
class NoMatch extends Component{
render(){
return(
<div style={{textAlign: 'center', fontSize:'24'}}>
404 No Found !!!
</div>
);
}
}
export default NoMatch;
注:项目来自慕课网
【共享单车】—— React后台管理系统开发手记:Router 4.0路由实战演练的更多相关文章
- 【共享单车】—— React后台管理系统开发手记:主页面架构设计
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:Redux集成开发
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:城市管理和订单管理
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:UI菜单各个组件使用(Andt UI组件)
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:AntD Form基础组件
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:权限设置和菜单调整(未完)
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:员工管理之增删改查
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:项目工程化开发
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
- 【共享单车】—— React后台管理系统开发手记:AntD Table高级表格
前言:以下内容基于React全家桶+AntD实战课程的学习实践过程记录.最终成果github地址:https://github.com/66Web/react-antd-manager,欢迎star. ...
随机推荐
- PAT——乙级1032
这些题也确实简单,但是我还是想做做,多熟悉一下C++,毕竟实践是检验真理的唯一标准,有很多小知识点自己做了才知道. 这个题是 1032 挖掘机技术哪家强 (20 point(s)) 为了用事实说明挖掘 ...
- [oldboy-django][2深入django]老师管理--查看,添加,编辑
# 添加老师(下拉框多选) 数据库设计: class Teacher(models.Model): name = models.CharField(max_length=64) cls = model ...
- kvm配置虚拟机[待整理]
working note 4-12-2016 1,利用libvirt图形虚拟机管理工具virt-manager搭建虚拟机,通过存储池(storage pool )和卷(volume)存放虚拟机镜像(I ...
- nyoj 题目6 喷水装置
喷水装置(一) 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以 ...
- python正则 转
python中的正则表达式(re模块) 一.简介 正则表达式本身是一种小型的.高度专业化的编程语言,而在python中,通过内嵌集成re模块,程序媛们可以直接调用来实现正则匹配.正则表达式模式被编 ...
- BZOJ1562 [NOI2009]变换序列 【KM算法】
题目 输入格式 输出格式 输入样例 5 1 1 2 2 1 输出样例 1 2 4 0 3 提示 30%的数据中N≤50: 60%的数据中N≤500: 100%的数据中N≤10000. 题解 每个位置可 ...
- http content-type总结
content-type 媒体类型,即MIME类型,包括媒体格式和编码两部分 例如:Content-Type:text/html;charset:utf-8 常见的媒体格式类型如下: text/htm ...
- openssl Rsa 分段加密解密
密钥长度 1024 openssl genrsa -out rsa_private_key.pem openssl rsa -in rsa_private_key.pem -pubout -out r ...
- pat 团体天梯赛 L2-006. 树的遍历
L2-006. 树的遍历 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 给定一棵二叉树的后序遍历和中序遍历,请你输出其层序遍历 ...
- Codeforces 899 C.Dividing the numbers-规律
C. Dividing the numbers time limit per test 1 second memory limit per test 256 megabytes input s ...

