[react基础] 路由 声明式路由 编程式路由 路由传参 嵌套路由 路由渲染方式(component render children) withRouter 自定义导航组件

1、介绍

现代的前端应用大多数是SPA(单页应用程序),也就是只有一个HTML页面的应用程序。因为它的用户体验更好、对服务器压力更小,所以更受欢迎。为了有效的使用单个页面来管理多页面的功能,前端路由应运而生。

  1. 前端路由功能:让用户从一个视图(组件)导航到另一个视图(组件)
  2. 前端路由是一套映射规则,在React中,是URL路径与组件的对应关系
  3. 使用React路由简单来说,就是配置路径和组件

在这里插入图片描述

2、路由使用

https://reactrouter.com/

2.1、相关组件

  1. Router组件:包裹整个应用,一个React应用只需要使用一次
    Router: HashRouter和BrowserRouter
    • HashRouter: 使用URL的哈希值实现 (localhost:3000/#/first)
    • BrowserRouter:使用H5的history API实现(localhost3000/first)
  2. Link/NavLink组件:用于指定导航链接(a标签)
    最终Link会编译成a标签,而to属性会被编译成 a标签的href属性
  3. Route组件:指定路由展示组件相关信息(组件渲染)
    • path属性:路由规则,这里需要跟Link组件里面to属性的值一致
      -component属性:展示的组件

各组件关系示意图
在这里插入图片描述

2.2、安装路由模块

路由模块不是react自带模块,需要安装第3方模块
npm i -S react-router-dom@5
定义项目使用路由,在入口文件/src/index.js文件中定义路由模式
在这里插入图片描述
定义路由规则和匹配成功的渲染组件
在这里插入图片描述
在浏览器中输入后尝试匹配
在这里插入图片描述

3、声明式导航

使用Link或NavLink组件完成声明式导航的定义

Link组件

Link组件不会根据路由的变化而添加或修改编译后html标签中的属性
在这里插入图片描述

NavLink组件

NavLink会根据路由的变化而自动修改编译后html标签中的属性

如果当前的路由规则和Navlink中的To所写的规则一致,则添加class样式,默认名称为 active,可以通过activeClassName来修改匹配成功后样式名称。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

exact

exact是Route下的一个属性,react路由会匹配到所有能匹配到的路由组件,exact能够使得路由的匹配更严格一些。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
访问/about时候,/也会匹配到,也会显示/对应组件,就是home组件,就显示了home的内容,这样就不对了,加上exact,就正常了

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

4、编程式导航

react-router-dom中通过history对象中的push/replace/goBack等方法实现编程式导航功能。

编程式导航
在react-router-dom中,
只要是路由规则匹配成功后,直接渲染的组件中,它的this.props中都会有3个路由对象
this.props.history   此对应就是用来完成编程式导航所用 push/replace/goBack
this.props.match     获取路由对象中的数据
this.props.location  获取路由对象中的数据

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

跳转

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

5、页面路由数据传递

路由参数:在Route定义渲染组件时给定动态绑定的参数。
React路由传参方式有三种:

1. 动态路由参数(param)

以“/detail/:id”形式传递的数据
在落地组件中通过this.props.match.params得到

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

2. 查询字符串(search)

通过地址栏中的 ?key=value&key=value传递
在落地组件中通过this.props.location.search得到

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

3. 隐式传参(state),通过地址栏是观察不到的

通过路由对象中的state属性进行数据传递
在落地组件中通过this.props.location.state得到

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

6、嵌套路由

在有一些功能中,往往请求地址的前缀是相同的,不同的只是后面一部份,此时就可以使用多级路由(路由嵌套)来实现此路由的定义实现。

例如,路由规则如下

admin/index
admin/user

它们路由前缀的admin是相同的,不同的只是后面一部份。
实现方式
先需要定义个组件,用于负责匹配同一前缀的路由,将匹配到的路由指向到具体的模块

<Route path="/admin" component={Admin}></Route>
// 创建模块路由组件负责指定各个路由的去向
render() {
    // 获取前缀,供后续地址做路由拼接
    let prefix = this.props.match.path;
    return (
        <div>
            <h1>欢迎使用后台管理程序</h1>
            <Route path={`${prefix}/user`} component={User}></Route>
            <Route path={`${prefix}/goods`} component={Goods}></Route>
        </div>
    );
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

重定向 404 路由参数类型限制 可选参数

在这里插入图片描述

7、路由渲染方式

7.1、component (组件对象或函数)

<Route path="/home" component={Home} /><Route path="/home" component={(router)=><Home {…router} />} />
类静态

它渲染的组件通过this.props能够得到路由对象

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

如果Route所在的组件中有数据更改,则它对应匹配的组件不进行创建,无操作
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

回调函数

性能不是太好,一般不建议去使用

它渲染的组件通过this.props无法得到路由对象,需要手动向下传递
在这里插入图片描述
在这里插入图片描述

如果Route所在的组件中有数据更改,则它对应匹配的路由组件则进行创建新的
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

因为它是回调函数的方式,所以它可以在匹配对应渲染的组件时,可以先进行逻辑判断 --模拟路由独享守卫
在这里插入图片描述

7.2、render (函数)

用它来一般完成路由独享守卫,它有component类渲染方式的优点也有component回调函数方式的优点

<Route path="/home" render={router=><Home {…router} />} />

在这里插入图片描述

7.3、children (函数或组件)

在组件渲染显示时,不是关注与它是否显示,而是在显示的时候关注于它的路由相关信息,才用到它
1.组件方法 精确匹配,地址栏中的规则和path路由一致它才匹配组件渲染,缺点:this.props中的路由对丢失

// 精确匹配
<Route path="/about" children={<About />} />

2.回调函数
全匹配,它不关心地址栏中的地址是否于当前path属性规则一致,它都渲染对应的组件,只不过在回调函数的router参数中,有一个match属性,如果地址栏中的地址和当前path路径一致,则match属性为对象,否为null,一般用children回调函数的方案
作用:视图中显示根据地址栏或路由中的某些字段来动态显示,我们可以用children回调函数方式.

// 全匹配
<Route path="/about" children={router =>{
	return <div>children渲染</div>
}} />


在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
用它来做404
在这里插入图片描述

8、withRouter高阶组件

作用:把不是通过路由直接渲染出来的组件,将react-routerhistory、location、match 三个对象传入props对象上

默认情况下必须是经过路由匹配渲染的组件才存在this.props,才拥有路由参数,才能使用编程式导航的写法,执行this.props.history.push('/uri')跳转到对应路由的页面,然而不是所有组件都直接与路由相连的,当这些组件需要路由参数时,使用withRouter就可以给此组件传入路由参数,此时就可以使用this.props

// 引入withRouter
import { withRouter} from 'react-router-dom'

// 执行一下withRouter
export default withRouter(Cmp)

或者
@withRouter

例子1:App组件不是通过路由直接渲染出来的组件

在这里插入图片描述

例子2:点击按钮跳转页面

在这里插入图片描述
所以withRouter的作用就是, 如果我们某个东西不是一个Router, 但是我们要依靠它去跳转一个页面, 比如点击页面的button, 返回Home页, 这时候就可以使用withRouter来做.

上面使用装饰器的写法,下面换种写法
在这里插入图片描述

例子3:需要先登录才能访问user页面

模拟全局导航守卫
在这里插入图片描述

在这里插入图片描述

9、自定义导航组件

为何需要自定义导航?
因为在项目中往往不是所有的声明式导航都是需要a标签完成,有时候可能需要别的标签,此时如果在需要的地方去写编程式导航就会有代码重复可能性,就在对于公共代码进行提取。

思路:

  1. 定义一个普通组件可以是类组件也可以是函数式组件
  2. 父组件能向子组件传值 props ,限制数据类型
  3. 此高阶组件不管路由规则是否匹配都要有渲染 children

在这里插入图片描述

在这里插入图片描述

需求:
当前url=user
给页面中的跳转到user的导航加上active
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

chiledren回调函数形式:如果地址栏中的地址和当前path路径一致,则match属性为对象,否为null,



参考:

Route的exact属性

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值