第六章:react-router4

6.1. 相关理解

6.1.1. react-router 的理解

  1. react 的一个插件库

  2. 专门用来实现一个 SPA 应用

  3. 基于 react 的项目基本都会用到此库

6.1.2. SPA 的理解

  1. 单页 Web 应用(single page web application,SPA)

  2. 整个应用只有一个完整的页面

  3. 点击页面中的链接不会刷新页面, 本身也不会向服务器发请求

  4. 当点击路由链接时, 只会做页面的局部更新

  5. 数据都需要通过 ajax 请求获取, 并在前端异步展现

6.1.3. 路由的理解

  1. 什么是路由?

a. 一个路由就是一个映射关系(key:value)

b. key 为路由路径, value 可能是 function/component

  1. 路由分类

a. 后台路由: node 服务器端路由, value 是 function, 用来处理客户端提交的请求并返回一个响应数据

b. 前台路由: 浏览器端路由, value 是 component, 当请求的是路由 path 时, 浏览器端前没有发送 http 请求, 但界面会更新显示对应的组件

  1. 后台路由

a. 注册路由: router.get(path, function(req, res))

b. 当 node 接收到一个请求时, 根据请求路径找到匹配的路由, 调用路由中的函数来
处理请求, 返回响应数据

  1. 前端路由

a. 注册路由: <Route path="/about" component={About}>

b. 当浏览器的 hash 变为#about 时, 当前路由组件就会变为 About 组件

6.1.4. 前端路由的实现

  1. history 库

a. 网址: https://github.com/ReactTraining/history

b. 管理浏览器会话历史(history)的工具库

c. 包装的是原生 BOM 中 window.history 和 window.location.hash

  1. history API

a. History.createBrowserHistory(): 得到封装 window.history 的管理对象

b. History.createHashHistory(): 得到封装 window.location.hash 的管理对象

c. history.push(): 添加一个新的历史记录

d. history.replace(): 用一个新的历史记录替换当前的记录

e. history.goBack(): 回退到上一个历史记录

f. history.goForword(): 前进到下一个历史记录

g. history.listen(function(location){}): 监视历史记录的变化

  1. 测试

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><title>history test</title></head><body><p><input type="text"></p><a href="/test1" onclick="return push('/test1')">test1</a><br><br><button onClick="push('/test2')">push test2</button><br><br><button onClick="back()">回退</button><br><br><button onClick="forword()">前进</button><br><br><button onClick="replace('/test3')">replace test3</button><br><br><script type="text/javascript"src="https://cdn.bootcss.com/history/4.7.2/history.js"></script><script type="text/javascript">let history = History.createBrowserHistory() // 方式一// history = History.createHashHistory() // 方式二// console.log(history)function push (to) {history.push(to)return false}function back() {history.goBack()}function forword() {history.goForward()}function replace (to) {history.replace(to)}history.listen((location) => {console.log(' 请求路由路径变化了', location)})</script></body>
</html>

6.2. react-router 相关 API

6.2.1. 组件

  1. <BrowserRouter>
  2. <HashRouter>
  3. <Route>
  4. <Redirect>
  5. <Link>
  6. <NavLink>
  7. <Switch>

6.2.2. 其它

  1. history 对象

  2. match 对象

  3. withRouter 函数

6.3. 基本路由使用

6.3.1. 效果

6.3.2. 准备

  1. 下载 react-router: npm install --save react-router@4

  2. 引入 bootstrap.css: <link rel="stylesheet" href="/css/bootstrap.css">

6.3.3. 路由组件: views/about.jsx

import React from 'react'
export default function About() {return <div>About 组件内容</div>
}

6.3.4. 路由组件: views/home.jsx

import React from 'react'
export default function About() {return <div>Home 组件内容</div>
}

6.3.5. 包装 NavLink 组件: components/my-nav-link.jsx

import React from 'react'
import {NavLink} from 'react-router-dom'
export default function MyNavLink(props) {return <NavLink {...this.props} activeClassName='activeClass'/>
}

6.3.6. 应用组件: components/app.jsx

import React from 'react'
import {Route, Switch, Redirect} from 'react-router-dom'
import MyNavLink from './components/my-nav-link'
import About from './views/about'
import Home from './views/home'
export default class App extends React.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">{/* 导航路由链接 */}<MyNavLink className="list-group-item" to='/about' >About</MyNavLink><MyNavLink className="list-group-item" 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 path='/home' component={Home} /><Redirect to='/about' /></Switch></div></div></div></div></div>)}
}

6.3.7. 自定义样式: index.css

.activeClass {color: red !important;
}

6.3.8. 入口 JS: index.js

import React from 'react'
import ReactDOM from 'react-dom'
import {BrowserRouter, HashRouter} from 'react-router-dom'
import App from './components/app'
import './index.css'
ReactDOM.render((<BrowserRouter><App /></BrowserRouter>/*<HashRouter>
<App />
</HashRouter>*/),document.getElementById('root')
)

6.4. 嵌套路由使用

6.4.1. 效果

6.4.2. 二级路由组件: views/news.jsx

import React from 'react'
export default class News extends React.Component {state = {newsArr: ['news001', 'news002', 'news003']}
render () {return (<div><ul>{this.state.newsArr.map((news, index) => <li key={index}>{news}</li>)}</ul></div>)
}
}

6.4.3. 二级路由组件: views/message.jsx

import React from 'react'
import {Link, Route} from 'react-router-dom'
export default class Message extends React.Component {state = {messages: []}componentDidMount () {// 模拟发送 ajax 请求setTimeout(() => {const data = [{id: 1, title: 'Message001'},{id: 3, title: 'Message003'},{id: 6, title: 'Message006'},]this.setState({messages: data})}, 1000)}render () {const path = this.props.match.pathreturn (<div><ul>{this.state.messages.map((m, index) => {return (<li key={index}><Link to='???'>{m.title}</Link></li>)})}</ul></div>)}
}

6.4.4. 一级路由组件: views/home.jsx

import React from 'react'
import {Switch, Route, Redirect} from 'react-router-dom'
import MyNavLink from './components/my-nav-link'
import News from './views/news'
import Message from './views/message'
export default function Home() {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 path='/home/message' component={Message} /><Redirect to='/home/news'/></Switch></div></div>)
}

6.5. 向路由组件传递参数数据

6.5.1. 效果

6.5.2. 三级路由组件: views/message-detail.jsx

import React from 'react'
const messageDetails = [{id: 1, title: 'Message001', content: ' 我爱你,  中国'},{id: 3, title: 'Message003', content: ' 我爱你,  老婆'},{id: 6, title: 'Message006', content: ' 我爱你,  孩子'},
]
export default function MessageDetail(props) {const id = props.match.params.idconst md = messageDetails.find(md => md.id===id*1)return (<ul><li>ID: {md.id}</li><li>TITLE: {md.title}</li><li>CONTENT: {md.content}</li></ul>)
}

6.5.3. 二级路由组件: views/message.jsx

import React from 'react'
import {Link, Route} from 'react-router-dom'
import MessageDetail from "./views/message-detail"
export default class Message extends React.Component {state = {messages: []}componentDidMount () {// 模拟发送 ajax 请求setTimeout(() => {const data = [{id: 1, title: 'Message001'},{id: 3, title: 'Message003'},{id: 6, title: 'Message006'},]this.setState({messages: data})}, 1000)}render () {const path = this.props.match.pathreturn (<div><ul>{this.state.messages.map((m, index) => {return (<li key={index}><Link to={`${path}/${m.id}`}>{m.title}</Link></li>)})}</ul><hr/><Route path={`${path}/:id`} component={MessageDetail}></Route></div>)}
}

6.6. 多种路由跳转方式

6.6.1. 效果

6.6.2. 二级路由: views/message.jsx

import React from 'react'
import {Link, Route} from 'react-router-dom'
import MessageDetail from "./views/message-detail"
export default class Message extends React.Component {state = {messages: []}componentDidMount () {// 模拟发送 ajax 请求setTimeout(() => {const data = [{id: 1, title: 'Message001'},{id: 3, title: 'Message003'},{id: 6, title: 'Message006'},]this.setState({messages: data})}, 1000)}ShowDetail = (id) => {this.props.history.push(`/home/message/${id}`)}ShowDetail2 = (id) => {this.props.history.replace(`/home/message/${id}`)}back = () => {this.props.history.goBack()}forward = () => {this.props.history.goForward()}render () {const path = this.props.match.pathreturn (<div><ul>{this.state.messages.map((m, index) => {return (<li key={index}><Link to={`${path}/${m.id}`}>{m.title}</Link>&nbsp;<button onClick={() => this.ShowDetail(m.id)}>查看详情(push)</button>&nbsp;<button onClick={() => this.ShowDetail2(m.id)}>查看详情(replace)</button></li>)})}</ul><p><button onClick={this.back}>返回</button>&nbsp;<button onClick={this.forward}>前进</button>&nbsp;</p><hr/><Route path={`${path}/:id`} component={MessageDetail}></Route></div>)}
}

第六章:react-router4相关推荐

  1. Vue实战狗尾草博客管理平台第六章

    Vue实现狗尾草博客后台管理系统第六章 本章节内容 文章列表 文章详情 草稿箱 文章发布. 本章节内容呢,开发的很是随意哈,因为多数就是element-ui的使用,熟悉的童鞋,是可以很快完成本章节的内 ...

  2. 王道考研 计算机网络笔记 第六章:应用层

    本文基于2019 王道考研 计算机网络: 2019 王道考研 计算机网络 个人笔记总结 第一章:王道考研 计算机网络笔记 第一章:概述&计算机网络体系结构 第二章:王道考研 计算机网络笔记 第 ...

  3. JavaScript高级程序设计(第3版)第六章读书笔记

    第六章 面向对象的程序设计 1. 数据属性 [[Configurable]]:表示能否通过delete删除属性从而重新定义属性.默认值为true. [[Enumerable]]:表示能否通过for-i ...

  4. 数字图像处理——第六章 彩色图像处理

    数字图像处理--第六章 彩色图像处理 文章目录 数字图像处理--第六章 彩色图像处理 1 彩色模型 1.1 RGB彩色模型 1.2 CMY 和CMYK彩色模型 1.3 HSI彩色模型 2 伪彩色图像处 ...

  5. java三维滑雪,第六章 三维数据空间分析方法.ppt

    第六章 三维数据空间分析方法 * * * * 可视性分析 * * 自然邻域法插值 基本思路: 利用输入点及邻近栅格单元进行插值生成栅格表面. 方法: 利用输入数据点(样本点)为节点,建立Delauna ...

  6. Knockout应用开发指南 第六章:加载或保存JSON数据

    原文:Knockout应用开发指南 第六章:加载或保存JSON数据 加载或保存JSON数据 Knockout可以实现很复杂的客户端交互,但是几乎所有的web应用程序都要和服务器端交换数据(至少为了本地 ...

  7. ASP.NET2.0自定义控件组件开发 第六章 深入讲解控件的属性

    深入讲解控件的属性持久化(一) 系列文章链接: ASP.NET自定义控件组件开发 第一章 待续 ASP.NET自定义控件组件开发 第一章 第二篇 接着待续 ASP.NET自定义控件组件开发 第一章 第 ...

  8. 机器学习-第六章 支持向量机(SVM)

    机器学习-第六章 支持向量机(SVM) D系鼎溜关注 2020.02.09 21:19:41字数 1,131阅读 458 6.1 间隔与支持向量 开倍速观看视频之后,对课本所说的会更加了解. 支持向量 ...

  9. 第六章 非编码RNA鉴定

    第六章 非编码RNA鉴定  阅读量: 154 主要为RNA-seq相关知识,部分内容作笔记自查使用.如有错误或遗漏还请海涵,可评论或邮箱联系. 最后修改时间:2020-09-07 14:38:07 星 ...

最新文章

  1. csgo怎么控制电脑玩家_图文详解电脑怎么发起远程控制
  2. Python 列表和元组
  3. 卖萌屋算法工程师思维导图part3—深度学习篇
  4. mysql 分号子查询_MySQL子查询详解
  5. matlab 大数阶乘,紧急求助:怎么用matlab计算1000的阶乘啊?
  6. mysql中括号_如何快速学习mySQL数据库常规通配符及运算符的用法?
  7. 新冠病毒做进化树covidseq
  8. 玩转数据魔方之数据安全治理进阶指南
  9. mht转html保留图片,【JAVA】mht文件转html
  10. C# 将raw格式的二进制灰度图像转为正常位图格式
  11. html5制作电子日历,基于HTML5的日历制作软件
  12. Spring Boot自定义starter
  13. python中类名(..)(..)的情况及_call_函数解析
  14. HTML小白学习-1.0
  15. mysql 数据转移历史表_mysql 历史数据表迁移方案
  16. 抖音矩阵号搭建及开发思路分享丨抖音矩阵源码丨抖音矩阵号运营
  17. 机器学习中的方差与偏差
  18. ADI Blackfin DSP处理器-BF533的开发详解61:DSP控制ADXL345三轴加速度传感器-LCD(含源码)
  19. java基础知识之一:命名规则(包名、类名、变量名、方法名)
  20. 自制快速冒烟测试小工具--基于python多线程

热门文章

  1. java 搭建个人博客_Spring boot 搭建个人博客系统(一)——整体思路
  2. android 字体空格,android – 在textview中设置字母之间的空格
  3. VGA、DVI、HDMI区别
  4. java等待5秒_Java并发编程-主线程等待子线程解决方案
  5. 操作行内样式-对象语法//操作行内样式-数组语法
  6. 剑指offer python版 最长不含重复字符的子字符
  7. python内置函数 exec eval compile
  8. css的一些常见问题处理方法
  9. GJM: Unity3D基于Socket通讯例子 [转载]
  10. thinkjs——空对象判断