知识点01-React路由配置
路由:在前端框架里面,单页面应用开发一般都要配合路由类完成。
后端路由
作用:将请求的URL地址和对应Nodejs函数关联在一起
http://web.woninlab.com:8005/add/useradd
http://web.woniulab.com:8005/registers 404 get post
将你的路径发送给指定的服务器,web.woninlab.com来进行定位。8005定位你服务器里面某个应用程序
/add/useradd:定位到你应用程序里面的某个代码片段
router.get("/add/useradd",function(req,res,next){
Controller处理业务
})
router.post("/add/stuadd",function(){
})
总结:后端路由的作用,就是将你的浏览器URL地址和Nodejs里面函数绑定在一起,执行对应的业务逻辑
前端路由
前端路由和路由都是一样的作用,但是前端路由作用对象不一样
http://127.0.0.1:3000/user
将浏览器地址和页面的UI组件绑定在一起。
使用路由的时候,会有几种模式。hash模式 history模式
不管是React框架还是Vue框架,路由实现都是基于Window对象里面history、location来完成的。只是他们提供的路由已经对底层代码做了封装,你直接配置文件就可以了。
window对象提供了history
你们使用history路由模式,需要用到history里面的两个api pushState replaceState(push、replace)
push(pushState):跳转过后会记录跳转历史记录。返回
replace(replaceState):不会记录历史记录,无法返回到上一级。默认返回
H5路由跳转
React路由搭建
React 官方并没有明确指定我们要使用哪个组件来完成路由设计,平时在开发过程中需要使用费路由可以用第三方的路由来搭配使用。推荐一个React-Router的组件来完成路由设计
React-Router能够完成路由的基础功能,hash功能,history、路由跳转、参数传递
访问React-Router组件:reactrouter.com/web/api/Red…
-
将路由组件下载到本地
yarn add react-router-dom npm install react-router-dom -
项目中引入路由组件
下载react-router-dom其实也是一个组件,import导入路由组件提供组件来完成路由配置
import {Route,Switch,Redirect,HashRouter} from "react-router-dom"通过react-router-dom引入你项目中需要的路由组件来搭建路由就可以
<HashRouter> {/* Switch组件相当于程序switch 默认匹配一个 */} <Switch> {/* 映射关系,将路径和UI组件映射在一起 */} <Route path="/login" component={Login}></Route> <Route path="/register" component={Register}></Route> </Switch> </HashRouter>在React中你要指定在哪个地方渲染路由,将这个配置放在指定的位置。默认作为渲染出口
-
路由配置的其他内容
路由器:也是两个不同的组件 HashRouter(hash路由器,使用这个路由器,地址栏出现hash#代码)BrowerRouter:使用常规的地址模式,地址栏里面没有#,一般在网站开发过程中你使用hash,最后项目上线的时候,推荐用正常模式。路径美观一些
路由匹配器:Switch和Router组件,Switch这个组件跟 编程switch代码是一个意思,代表默认只能匹配到一个结果,匹配成功后面就不会在执行。效率和性能,如果你的Swich在匹配过程中没有任何一个Router能够映射成功,默认返回null(不渲染任何内容)
特点就是匹配到一个就停止匹配。路径有可能会出现包含关系。后面匹配就失败
<Route exact path="/" component={Login}></Route>exact:代表精确匹配的意思,值不对那就无法映射
当你你不用exact匹配路由的时候,你可以将模糊的地址放在Switch最后,从精确到模糊匹配方式
<Route path="/login" component={Login}></Route> <Route path="/register" component={Register}></Route> <Route path="/" component={Login}></Route>对于Route这个组件,我们作用就是映射关系
<Route path="/login" component={Login}></Route> 替换为: {/* 插槽 */} <Route path="/register"> <Register></Register> </Route>推荐你们 用第一种方式,第二种方式在使用过程中,一级路由完成没有差别,但是如果你有二级路由嵌套。二级路由访问会出问题。
导航:路由配置成功后,我们通过导航来进行跳转
Link:这个组件可以跳转到指定的组件 router-link activeClass
NavLink:点击过后触发默认的一些配置,比如导航颜色
你可以直接在组件中使用他们来完成页面跳转。最终浏览器会将组件解析为a标签的方式来进行渲染
重定向:如果你获取到某个路径,这个路径暂时不需要组件来匹配,你可以重定向到其他组件
<Redirect exact from="/" to="/login" ></Redirect>from:匹配到的路径
to:重定向到哪个位置
知识点03-嵌套路由
在开发中我们将二级路由三级路由等等都统称为嵌套路由。在React中要配置嵌套路由,跟一级配置没有太大的区别,有些约定熟成的阿规范
二级路由的匹配规则
<div className="content">
{/* <BrowserRouter> */}
<Switch>
<Redirect exact from="/home" to="/home/flowrs"></Redirect>
<Route path="/home/flowrs" component={Main}></Route>
<Route path="/home/data" component={Data}></Route>
<Route path="/home/emp" component={Emp}></Route>
</Switch>
{/* </BrowserRouter> */}
</div>
在指定的组件里面在加载Switch,和Route组件,指定就在这个位置完成二级路由的渲染
需要注意:二级路由不需要在使用路由器。项目中只需要配置一级路由的路由器就可以完成页面跳转,路由匹配
知识点04-路由跳转
比如:从登录跳转到注册,从注册跳转登录。从登录跳转主页
一、通过导航组件来完成
Link = ""
NavLink to=""
二、脚本的跳转
在React的组件中,你需要跳转可以通过props里面传递的history对象来进行跳转
push:跳转过程中会记录历史记录,可以返回上次的记录
replace:替换了一个路径,无法在返回到上一页页面
navigateTo = ()=>{
console.log(this.props);
// this.props.history.push("/register")
this.props.history.replace("/register")
}
在框架里面提供的Link、NavLink router-link最终在webpack打包的时候默认都会解析为a标签/但是一般不推荐大家直接用。是因为在跳转的过程中,组件的方式需要做一些解析。包括后续参数传递。动态添加样式
在路由里面跳转的时候,props默认多了三个对象
history:代表历史记录,里面包含跳转的api,以及对路径一些api操作
location:跳转的路径信息,参数的匹配
match:也是对路径信息记录,参数一些匹配
组件的分类:
-
路由组件:页面,登录、注册、主页、main这些都是通过路由来进行加载
-
非路由组件:import的方式引入到指定的组件中
非路由组件身上默认不会给props添加路由的三个对象。无法跳转
非路由组件无法获取到history,你可以使用下面的方案来解决
-
路由组件将props的对象传递给子组件,可以继续往下传递,只要有history那就可以跳转
<Header {...this.props}></Header> logout =()=>{ // console.log("Header",this.props); this.props.history.push("/login") }缺点:如果组件嵌套比较多,每一层逐层传递,有些组件不需要也必须作为一个载体来获取history
-
可以通过高阶组件来完成效果
高阶段组件:本质上也是一种组件,但是高阶组件可以接受一个组件作为参数。返回一个新的组件。
高阶函数:定义一个函数,这个函数接受一个函数作为参数,最后在返回一个函数。
高阶组件就是一种特殊的高阶函数,高阶组件的代码,最终以高阶函数的形式存在
闭包:闭包不需要接受一个函数。
function add(fn1){ //对原来的函数进行增强处理 return function(){ //处理完成过后的函数结果 } }IIFE就是典型高阶函数
function map(fn1){ array let newarray = [] for(let i=0,i<array.length;i++){ fn1(array[i]) newarray.push*() } return newarray } const arr = array.map(function(item){ console.log(item) })高阶组件如何完成:需要引入withRouter这个组件来对原来组件进行包装
import React, { Component } from 'react' import {Link,withRouter} from "react-router-dom" // import Content from "xxx" class Header extends Component { logout =()=>{ console.log("Header",this.props); // this.props.history.push("/login") } render() { return ( <div style={{width:"100%",height:"80px",backgroundColor:"black"}}> <button onClick={this.logout}>注销</button> <Link to="/login">注销</Link> </div> ) } } export default withRouter(Header) 在暴露对组件,需要将Header组件放在withRouter里面进行组件的包装,当前这个组件身上props就默认会添加三个路由对象
模拟高阶组件实现:
const withRouter = (comp)=>{ return ()=>{ return <Route component={comp}> } }
知识点05-路由参数传递
在页面直接使用路由跳转的时候,可以给其他组件传递参数,用于数据更新
应用场景:查看详情、修改数据
window.location.href="/home?id=1&name=xiaowang"
const url = window.location.href
window.location.search()
url.split("?")[1].split("&")
//es6 Set Map
const map = new Map()
map.put()
const object = {}
object["id"] = 1;
params获取参数
React动态路由参数传递方式
在路由配置的时候,路径上面添加/:name
<Route path="/register/:name/:address" component={Register}></Route>
跳转的时候,需要在路径上面添加数据
<Link to="/register/xiaowang/gaoxin">回到注册</Link>
this.props.push("/register/xiaowang/gaoxin")
在组件中,通过props可以接收到路由的参数
render(){
console.log(this.props.match.params)
}
这种方式获取到参数,刷新页面,数据还存在。而且路径显示的时候也比较美观
query对象获取参数
传递参数的时候
<Link to={{pathname:"/login",query:{name:"xiaowang",address:"武侯区"}}}>跳转登录</Link>
<button onClick={this.navigateTo}>跳转登录</button>
navigateTo = ()=>{
this.props.history.push({
pathname:"/login",
query:{
name:"xiaofeifei"
}
})
}
获取参数需要通过location对象来获取
this.props.location.query
优点:传递的参数不会显示地址栏,可以传递对象到跳转到组件。
缺点:页面刷新数据会丢失
state的方式传递参数
在传递参数的时候,可以自己定义一个state的对象传递给跳转组件
<Link to={{pathname:"/login",state:{name:"tom"}}}>State的方式跳转登录</Link>
自定义对象属性
Search方式传递参数
可以传递多个参数,需要对参数做一个构造
<Link to="/login?phone=138123456&name=xiaozhang">Search传递参数</Link>
获取参数
this.props.location.search
好处就是:刷新页面数据依然存在,
缺点:参数如果非常多的时候,地址显示非常长
知识点06-路由懒加载
React路由懒加载也是为了提高程序的运行效率。
在React中只要你在组件中,或者在路由中使用import的方式来加载组件,程序在启动的时候,加载你引入组件。
启动的时候花费的时候比较长。
React在以前的老版本里面并没有提供路由懒加载的功能。我们需要使用第三方的懒加载插件,目前React版本里面已经提供了路由懒加载策略。
- 基于第三方的懒加载插件完成路由动态加载
- 使用React官方提出的懒加载策略
Vue中路由懒加载
component:()=>import ("./Login")
Loadable插件完成
这是一种比较旧的懒加载方式,这种方式作为了解
-
下载loadable插件
yarn add react-loadable -
将插件引入到项目中
import Loadable from "react-loadable" const Login = Loadable({ loader:()=>import("./views/Login"), loading:()=><div>...加载中</div> }) const Register = Loadable({ loader:()=>import("./views/Register"), loading:()=><div>...加载中</div> }) const Home = Loadable({ loader:()=>import("./views/Home"), loading:()=><div>...加载中</div> })loader:要加载的组件,import来动态加载
loading:加载过程执行的动画,你可以封装为一个组件,调用
React推荐的路由懒加载
-
使用React官网推荐的组件包裹我们路由器
<React.Suspense fallback={<Loading></Loading>}> <BrowserRouter> <Switch> <Redirect exact from="/" to="/home"></Redirect> <Route path="/login" component={React.lazy(()=>import("./views/Login"))}></Route> <Route path="/register" component={React.lazy(()=>import("./views/Register"))}></Route> <Route path="/" component={React.lazy(()=>import("./views/Home"))}></Route> </Switch> </BrowserRouter> </React.Suspense>你需要在路由器组件外面增加一个组件,Suspense,提供一个fallback,当网络加载比较慢的情况下,我们可以提供加载动画,你可以是组件也可以是标签
-
使用lazy函数来完成组件的动态加载
<Route path="/register" component={React.lazy(()=>import("./views/Register"))}></Route>跟Vue中懒加载很相似,在component加载组件的时候,动态import一次