上节课我们简单的聊了一下路由跳转的两种模式,这节课我们来学习一下关于编程式路由导航的相关内容。

回顾

在开始这节课的内容之前,我们先来对上节课来做一个简单的回顾。

  • 路由跳转有两种模式
  • push模式
  • replace模式

以上便是上节课的主要内容,接下来我们来学习编程式路由导航的相关内容。

什么是编程式路由导航

我们来回想一下我们的案例,我们每个导航区都可以实现路由跳转。注意我们说的是路由跳转,不是链接跳转。那我们的路由跳转都是怎么实现的呢?是不是通过Link组件或者是NavLink组件来实现的?但是这些都是文字,如果说我们要通过一张图片来实现路由跳转怎么办?可能有人要说那简单,我们直接在图片外面包一层Link组件就行了啊,当然没问题。但是大家听我下面这个需求。

我们之前的案例,我给加上重定向之后,打开页面是不是自动就跳转到/home/news了啊?那么我现在要求News展示 3 秒之后自动跳转到Message,这个应该怎么实现?你还能通过Link或者NavLink组件来实现吗?肯定不能了。因为我们Link也好或者NavLink也罢,都要有人点才能跳转。

那么我们通过一段代码,使得我们没有人去点击也能实现路由跳转的话,这一步操作就叫编程式路由导航。

案例需求

那么我们知道了编程式路由导航大概是怎么一回事儿了之后,我们来看看怎么用吧。比如我们现在有这么个需求。

image-20220117153604881

我们依然还是之前的案例,我们希望每条消息后面都能有两个按钮,一个叫push 查看吗,另一个则是replace 查看。那么这个需求我们应该怎么实现呢?

分析

我们还记不记得我们之前一般组件和路由组件的区别?最大的区别是什么?是不是接收到的props?路由组件会收到三个固定属性

  • history里面包含一些API以及location属性和match属性
  • location属性,接收search参数和state参数
  • match接收params参数

我们在看history属性的时候是不是看见了几个特殊的属性,那几个都是路由特有的API

  • push
  • replace
  • goBack
  • goForward
  • go
  • ...

其实这里的pushreplace就是我们用于改变跳转模式的API,那我们直接调用这些API不就可以实现我们的效果了嘛

实现

export default class Message extends Component {
  state = {
    messageArr: [
      { id: 1, title: "message001" },
      { id: 2, title: "message002" },
      { id: 3, title: "message003" },
    ]
  }
  render() {
    const { messageArr } = this.state
    return (
      <div>
        <ul>
          {messageArr.map(
            msg => <li key={msg.id}>
              <Link to={`/home/message/details/{msg.id}/{msg.title}`}>
                {msg.title}
              </Link>&nbsp;
              <button>push 查看</button>&nbsp;
              <button onClick={()=>this.replaceShow(msg.id,msg.title)}>
                replace 查看
              </button>
            </li>
          )}
        </ul>
        <Route path="/home/message/details/:id/:title" component={Details} />
      </div>
    )
  }
  replaceShow = (id,title) => {
    this.props.history.replace(`/home/message/details/{id}/{title}`)
  }
}

我们为了方便观察,我们使用params参数。首先是不是添加按钮,然后绑定onClick事件?因为默认是push,那么我们就先来写replacereplace APIprops.history中,那么我们就来调用一下,然后传入我们的路径,因为我们要传参的,所以说要在replaceShow方法中来接收参数。那么我们在给onClick事件加回调的时候就要写成一个箭头函数的形式,从而使得replaceShow方法能接收到参数。那么我们来看一下效果:

image-20220117155531491

我点击了message001replace 查看,页面正常展示了message001的信息。那么这个时候栈顶的数据是谁?是不是message001?那么/home/message还在不在?是不是已经被替换掉了?所以说我们这个时候点击后退按钮是不是就直接退到了/home/news

image-20220117155751440

从图上来看的话,我们的replace 查看按钮的功能是完全没问题的。push查看也是相同的原理,我就不做赘述了。

编程式路由携带参数

那么我们目前的用的是不是params参数?那么我们如果想用search参数的话是不是就改一下API中接收的路径来修改一下传参方式就行了?当然了我们要把声明接收改一下就行了?

那么如果我们要携带state参数怎么办?直接把路径该写成对象就行了吗?那么我们来看一下呗:

image-20220117160440447

这里面是不是有一个state参数?那我们还写成对象干什么呢,直接传参就行了啊。

export default class Message extends Component {
  state = {...}
  render() {
    const { messageArr } = this.state
    return (
      <div>
        <ul>
          {messageArr.map(
            msg => <li key={msg.id}>
              <Link to={`/home/message/details/{msg.id}/{msg.title}`}>
                {msg.title}
              </Link>&nbsp;
              <button>push 查看</button>&nbsp;
              <button onClick={()=>this.replaceShow(msg.id,msg.title)}>
                replace 查看
              </button>
            </li>
          )}
        </ul>
        <Route path="/home/message/details" component={Details} />
      </div>
    )
  }
  replaceShow = (id,title) => {
    this.props.history.replace(`/home/message/details`,{id,title});
  }
}

那么我们来看一下,state参数是不是要改一下注册方式?改成正常注册,然后在replaceShow方法中调用API,窜入路径,传入state参数对象。然后我们来看一下结果:

image-20220117161427683

我们这次使用了state参数,然后点击replace 查看按钮,现在页面正常展示了信息,然后点击后退按钮:

image-20220117161606177

退回到了/home/news

以上便是我们的history中的replace API,其中还有几个其他的API,大家可以自己测试一下。我这里就不多做赘述了。以上就是编程式路由跳转的内容。

总结

  • 编程式路由导航就是编写一段代码来完成路由的跳转
  • 编程是路由导航借助的就是路由组件所接收到的propshistory属性自身的API

Copyright statement:The articles of this site are all original if there is no special explanation, indicate the source please when you reprint.

Link of this article:https://work.lynchow.com/article/code_route_guide/