React路由初始

一、SPA单页面

1、单页Web应用(单个html)

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

3、点击页面中的链接不会刷新页面,只会做页面的局部刷新

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

二、路由的理解

1、什么是路由

一个路由就是一个映射关系(key:value);key为路径,value可能就是function或component

2、路由的分类

1)后端路由:value是fuction,用来处理客户端提交的请求;

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

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

2)前端路由:浏览器端路由,value是component,用于展示页面内容

注册路由:<Route path="test" component={Test}>

工作过程:当浏览器的path变为/test时,当前的路由组件就会变成Test组件

路由HISTORY有两种方式:History.createBrowserHistory(),直接使用H5推出的history身上的API;History.createHashHistory(),hash值(锚点)有历史记录,但是值的改变不会出发页面变化

3、react-router-dom的理解

react的一个插件库;专门用来实现一个SPA应用;基于react的下你项目基本都会用到此库。

1) Link、Route与BrowserRouter

javascript 复制代码
import { Link,BrowserRouter } from 'react-router-dom'


//在react中靠路由链接实现切换路由--编写路由链接
<BrowserRouter>
    <Link to="/about">关于</Link>
</BrowserRouter>
javascript 复制代码
import { Route,BrowserRouter } import 'react-router-dom'

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

浏览器地址栏为 https://xxx.xxx.xxx:xxxx/about

2)HashRouter

javascript 复制代码
import { Link,HashRouter } from 'react-router-dom'


<HashRouter>
    <Link to="/about">关于</Link>
</HashRouter>
javascript 复制代码
import { Route,HashRouter } import 'react-router-dom'


<HashRouter>
    <Route path="/about" component={About}/>
</HashRouter>

浏览器地址栏为 https://xxx.xxx.xxx:xxxx/#/about

注:由于Link与Route都需要BrowserRouter包裹,且不能在项目中多次出现<BrowserRouter>或<HashRouter>,我们在项目中的index.js里对<App>进行包裹

javascript 复制代码
import React from 'react'

import ReactDOM from 'react-dom'

import { BrowserRouter } from 'react-router-dom'

import App from './App

ReactDOM.render(
    <BrowserRouter>
        <App/>
    </BrowserRouter>,
    document.getElementById('root')
)

3)路由组件与一般组件

1.写法不同:

一般组件:<Demo />

路由组件:<Route path="/about" component={About}/>

2.存放的位置不同

一般组件:component

路由组件:pages

3.接收到的props不同

一般组件:写组件标签时传递了什么,就能接收到什么

路由组件:接收到3个固定的属性 history、location、match

如果实现如图所示的效果:点击About或Home的话,路由会高亮。按照bootstript的写法

javascript 复制代码
<BrowserRouter>
    <Link to="/about" active>About</Link>
    <Link to="/home">Home</Link>
</BrowserRouter>

需要在Link里添加active

javascript 复制代码
import { NavLink,BrowserRouter } from 'react-router-dom'

<BrowserRouter>
    <NavLink to="/about">About</NavLink>
    <NavLink to="/home">Home</NavLink>
</BrowserRouter>

使用NavLink的话,react就会默认添加了active,点击路由,被激活的路由自然而然加了背景色,此外如果觉得默认的样式不好看的话,可以在NavLink加"activeClassName"给路由添加激活状态的样式,这里的激活状态样式应该加高权重。

javascript 复制代码
import { React,{Component}} from 'react'
import { NavLink,BrowserRouter } from 'react-router-dom'

export default MyNavLink extends Component {
    render(){
        coonst { to,title } = this.props
        return (
            <BrowserRouter>
                <NavLink to={to}>{title}</NavLink>
            </BrowserRouter>
        )
    }
}
javascript 复制代码
<MyNavLink to="/ablut" title="关于"></MyNavLink>

此外,如果给MyNavLink传递的过多,可以直接用{...this.props}展开

javascript 复制代码
import { React,{Component}} from 'react'
import { NavLink,BrowserRouter } from 'react-router-dom'

export default MyNavLink extends Component {
    render(){
        coonst { title } = this.props
        return (
            <BrowserRouter>
                <NavLink {...this.props}>{title}</NavLink>
            </BrowserRouter>
        )
    }
}

另外如果我想以"<MyNavLink to="/ablut">关于</MyNavLink>"的形式呢?这也是可以封装的

上个代码示例中,打印this.props的话,会有个children属性

javascript 复制代码
import { React,{Component}} from 'react'
import { NavLink,BrowserRouter } from 'react-router-dom'

export default MyNavLink extends Component {
    render(){
        console.log(this.props)
        return (
            <BrowserRouter>
                <NavLink {...this.props} />
            </BrowserRouter>
        )
    }
}

6) Switch的使用

javascript 复制代码
import { Route,BrowserRouter } import 'react-router-dom'

<BrowserRouter>
     <Route path="/about" component={About}/>
     <Route path="/about" component={Home}/>
</BrowserRouter>

以上的情况:如果路由是"/about"的话,组件About和Home都会显示出来,也就是说路由在匹配到路由时会继续往下进行匹配,如果路由多的话,不仅会耗性能还会出现意想不到的内容下是出来,所以我们可以使用Switch进行包裹,当匹配到适合的路由就停止往下继续匹配

javascript 复制代码
import { Route,BrowserRouter,Switch } import 'react-router-dom'

<BrowserRouter>
    <Switch>
         <Route path="/about" component={About}/>
         <Route path="/about" component={Home}/>
    </Switch>
</BrowserRouter>

通常情况下,path与component是一一对应关系,Switch可以提高路由的匹配效率(单一匹配)

7)样式丢失问题

项目启动的本地路径http://XXX.XXX.XXX.XXX:XXXX,这是内置devServe服务器的请求地址,当后面跟的路径是在路由中不存在时(多级路由),react会默认展示为public文件下的index.html页面。

1、public/index.html中引入样式时,不写 ./ 要写 /

2、public/index.html中引入样式的改为"%PUBLIC_URL%/css"

2、在根组件使用HashRouter包裹

8)路由的模糊匹配

javascript 复制代码
import { Route,BrowserRouter,Switch } import 'react-router-dom'

<BrowserRouter>
    <Switch>
         <Route path="/home" component={Home}/>  //home页面
         <Route path="/home/a/b" component={Home}/>  //没有a文件b页面,依旧显示home
         <Route path="/a/home/b" component={Home}/>  //没有a文件b页面,什么也不显示
          //以上就是路由的模糊匹配,从左到右依次匹配,有就显示,如果开头就没有,就不继续往下进行匹        配

        //相反
        <Route exact={true} path="/home" component={Home}/> //严格匹配
        <Route exact path="/home" component={Home}/>  //严格匹配
    </Switch>
</BrowserRouter>

1.默认使用的是模糊匹配,输入的路径必须包含要匹配的路径,且顺序要一致

2.开启严格模式<Route exact={true} path="/home" component={Home}/>

3.严格匹配不要随便开启,需要时再开,有些时候开启会导致无法继续匹配二级路由

9)Redirct重定向

javascript 复制代码
import { Route,BrowserRouter,Switch,Redirct } import 'react-router-dom'

<BrowserRouter>
    <Switch>
        <Route path="/home" component={Home}/>
        <Route path="/about" component={About}/>
        <Redirct path="/home" />  //当路由没有/home、没有/about,页面会直接显示home页面。
    </Switch>
</BrowserRouter>

一般写在所有路由注册的最下方,当所有路由都无法匹配时,跳转到Redirect指定的路由

10)嵌套路由

javascript 复制代码
import { Route,BrowserRouter,Switch } import 'react-router-dom'

<BrowserRouter>
    <Switch>
         <Route path="/about/a" component={About}/>
         <Route exact path="/home/about" component={Home}/> //  路由是/home,页面是不会展示的
         <Redirct path="/home/b">
    </Switch>
</BrowserRouter>

1.注册子路由时要写上父路由的path值

2.路由的匹配是按照路由的顺序进行的

三、路由传参

1、向路由组件传递params参数

javascript 复制代码
import { BrowserRouter, Link,Route } from 'react-router-dom'

<BrowserRouter>
    //向路由组件传递params参数 
    <Link to="{`/about/${参数}`}" active>About</Link>


    //声明接收params参数
    <Route path="/about:params" component={About} />

    // <Link to="{`/about/${参数1}/{参数二}`}" active>About</Link>
    //<Route path="/about/:params1/:params2"component={About} />
</BrowserRouter>

在About组件中打印 this.props

this.props.match.params就是你传递的路由参数集合。

* 路由链接(携带参数) <Link to="/about/18">About</Link>

* 注册路由(声明接收) <Route path="/about/:params1" component={About} />

* 接收参数 const { params1 } = this.props.match.params

2、向路由组件传递search参数

java 复制代码
import { BrowserRouter, Link,Route } from 'react-router-dom'

<BrowserRouter>
    //向路由组件传递search参数 
    <Link to="{`/about/?params=${this.state.params1}`}">About</Link>

    //search无需声明,正常注册
    <Route path="/about" component={About} />
</BrowserRouter>

在About组件中,打印 this.props

开发中,参数最好是对象的形式。

querystring

React内置

javascript 复制代码
import qs from "querystring"

let obj = { name:'a',age:18 } 
qs.stringify(obj) //name=a&age=18


let str = 'name=a&age=18'
qs.parse(str) //{ name:'a',age:18 } 

3、向路由组件传递state参数

java 复制代码
import { BrowserRouter, Link,Route } from 'react-router-dom'

<BrowserRouter>
    //向路由组件传递state参数 
    <Link to="{`/about`,state:{ name:this.state.name,age:this.state.age }}">About</Link>

    <Route path="/about" component={About} />
</BrowserRouter>

在About组件中,打印 this.props

4、push和replace

路由默认是push模式,也就是说路由的变换在浏览器中是有记录的,可以正常执行浏览的回退操作。而replace是替换路由,在浏览器中是没有记录的,

javascript 复制代码
import { BrowserRouter, Link,Route } from 'react-router-dom'

<BrowserRouter>
    <Link replace={true} to="{`/about`,state:{ name:this.state.name,age:this.state.age }}">About</Link>

    //    <Link replace={true} to="{`/about`,state:{ name:this.state.name,age:this.state.age }}">About</Link>

    <Route path="/about" component={About} />
</BrowserRouter>
相关推荐
Data analyse45611 小时前
Cookie过期引发UV上涨的复核方法
服务器·前端·数据分析·uv
Highcharts.js11 小时前
图表开发实战总结| 7 条“黄金法则”与“性能铁律”
前端·javascript·vue.js·编辑器·时序数据库·highcharts
Helix25011 小时前
Electron、WebView 框架与 HTA 对比:桌面应用选型、安全性与现代替代方案
前端·javascript·electron·webview·vbscript·hta·本地html应用
开开心心就好11 小时前
办公软件卸载不干净?专用工具一键清残留
java·前端·人工智能·智能手机·kafka·excel·memcache
静默回滚11 小时前
图片能显示,画进canvas却空白:像素面积上限
前端
补码缩写11 小时前
canvas大图内存怎么算:宽×高×4只是第一份
前端
coding漫漫长路12 小时前
img.decode()报错的图能画,load成功的却是空的
前端
不可能片场12 小时前
AI视频首尾帧控制 用参考图定住镜头
前端·electron
修炼的dance12 小时前
canvas最大能开多大:先看面积,再看导出格式
前端
薛一半12 小时前
React-Redux核心原理与容器组件实战
前端·javascript·react.js