React:react-router-dom的学习总结

1.前言

使用了React、Vue等开发的应用都是SPA(单页面应用)。

什么是单页面应用呢?

特点:

  • 整个应用只有一个完整的页面。
  • 店家页面中的链接不会刷新页面,只会做页面的局部更新。
  • 数据都需要通过ajax请求获取,并在前端异步展现。

单页面应用想要实现多页面应用类似切换内容效果,那就离不开路由

React的路由是一个独立被分割出去的库,在使用路由前需使用下面命令在项目中引入该库:

cnpm install react-router-dom --save

2.路由基础

咋们由浅入深,先来学习最基础的路由使用。

静态路由示例:

index.js:

import React from 'react'
import ReactDOM from 'react-dom'
import App from './App.js'

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

App.js:

import React from 'react'
import {
    
     BrowserRouter as Router, Route, Link } from 'react-router-dom'
import './index.css'

function TakeOut(props) {
    
    
  return (
    <div>
      <h3>我是外卖页面</h3>
    </div>
  )
}

function Order(props) {
    
    
  return (
    <div>
      <h3>我是订单页面</h3>
    </div>
  )
}

function My(props) {
    
    
  return (
    <div>
      <h3>我是"我的"页面</h3>
    </div>
  )
}
export default class App extends React.Component {
    
    
  render() {
    
    
    return (
      <div>
        <h1>哈哈哈,傻瓜</h1>
        <Router>
          <div className="navigator">
            <Link to="/takeout">外卖</Link>
            <Link to="/order">订单</Link>
            <Link to="/me">我的</Link>
          </div>
          <div className="container">
            <Route path="/takeout" component={
    
    TakeOut}></Route>
            <Route path="/order" component={
    
    Order}></Route>
            <Route path="/me" component={
    
    My}></Route>
          </div>
        </Router>
      </div>
    )
  }
}

index.css:简单的css样式

* {
    
    
  margin: 0px;
  padding: 0px;
}
.navigator {
    
    
  display: flex;
  text-align: center;
}

.navigator a {
    
    
  flex: 1;
  font-size: 20px;
  text-decoration: none;
}
.container {
    
    
  height: 300px;
  padding: 50px;
  background-color: aqua;
}

结果:

在这里插入图片描述
在这里插入图片描述
React路由三个重要标签:

  • Router:可以把它看成一个盒子,里面包裹着Route、Link和其它任意标签,注意:Route、Link必须被包含在Router内部。

  • Route:该标签有两个作用

    • 1.该标签使用path、component、render等属性定义路由匹配规则。
    • 2.该标签作为占位符,即该标签映射的组件将在该标签的位置上进行展示。
  • Link:本质是一个a标签,用于点击实现切换页面组件。

3.如何获取动态路由参数(三种方式)

假设有这么一个需求,一个外卖商家列表,当用户点击某个店铺时,跳转到该店铺详情,那么每个店铺都有一个唯一的id,那么我们才知道用户进入的是哪个店铺,才知道该请求哪个店铺的详情。

3.1 Params参数

通过Params参数也有两种方式获取数据。

1.params方式:借用useParams库

App.js:

import React from 'react'
import {
    
    
  BrowserRouter as Router,
  Route,
  Link,
  useParams,
  Switch,
} from 'react-router-dom'
import './index.css'

function Child(props) {
    
    
  let {
    
     id } = useParams()
  return <div>{
    
    id}</div>
}

export default class App extends React.Component {
    
    
  render() {
    
    
    return (
      <div>
        <h1>哈哈哈,傻瓜</h1>
        <Router>
          <div className="navigator">
            <Link to="/takeout/123">一品鲜</Link>
            <Link to="/takeout/234">牛肉火锅</Link>
            <Link to="/takeout/456">糖水</Link>
          </div>

          <div className="container">
              <Route path="/takeout/:id" component={
    
    Child}></Route>
          </div>
        </Router>
      </div>
    )
  }
}

在这里插入图片描述
在这里插入图片描述
通过useParams可以很方便的获取动态路由的参数,得到某个店铺的id之后,就可以请求某个店铺的详情页面了。

2.Params方式:使用组件的props属性

除了使用useParams可以获取动态路由参数外,也可以使用传入组件的props获取,先看看props里面包含什么内容:

在这里插入图片描述
从图中可以看到,传入组件的props对象包含三个属性,其中match中的params就有动态路由的参数,那么我们可以直接使用props.match.params.id获取参数值。

function Child(props) {
    
    
  console.log(props)
  return <div>{
    
    props.match.params.id}</div>
}

精简总结:

路由链接(携带参数):<Link to=’/demo/test/tom/18’}>详情
注册路由(声明接收):
接收参数:this.props.match.params

3.2 search参数与state参数组合

当路由跳转,需要向组件传递一些非URL的数据时,我们应该怎么传递呢?什么是非URL数据?

看下面URL:

http://localhost:3000/takeout?id=123

这是一个完整的URL,在URL上我们可以获取它的路径/takeout以及获取id的查询参数,这些就是在URL上的数据。假如我还想告诉组件一些其它信息,则可以通过下面方式传递参数。

< Link >标签的to属性设置为一个对象,该对象可有下面这些属性:

  • pathname:路径,pathname:"/takeout"相当于to="/takeout".
  • search:查询参数,就比如上面URL中的?id=123
  • state:对象类型,可以放入任意传递给组件的数据。

示例:

function Child(props) {
  console.log(props)
  return <div>{props.location.state.shopName}</div>
}
export default class App extends React.Component {
  render() {
    return (
      <div>
        <h1>哈哈哈,傻瓜</h1>
        <Router>
          <div className="navigator">
            <Link
              to={
   
   {
                pathname: '/takeout',
                search: '?id=123',
                state: { shopName: '一品鲜' },
              }}
            >
              一品鲜
            </Link>
          </div>
          <div className="container">
            <Route path="/takeout" component={Child}></Route>
          </div>
        </Router>
      </div>
    )
  }
}

这样设置Link,则点击“一品鲜”跳转时,就可以将shopName数据传递给组件,state可以包含任意多数据。
在这里插入图片描述
从打印出来的props中,location可以找到我们路由跳转时传递的其它参数。

精简总结:

  		search参数
  					路由链接(携带参数):<Link to='/demo/test?name=tom&age=18'}>详情</Link>
  					注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
  					接收参数:this.props.location.search
  					备注:获取到的search是urlencoded编码字符串,需要借助querystring解析
  		3.state参数
  					路由链接(携带参数):<Link to={
    
    {pathname:'/demo/test',state:{name:'tom',age:18}}}>详情</Link>
  					注册路由(无需声明,正常注册即可):<Route path="/demo/test" component={Test}/>
  					接收参数:this.props.location.state
  					备注:刷新也可以保留住参数

5. 路由重要属性属性

1.basename:所有路由的基础路径。

        <Router basename="shop">
          <div className="navigator">
            <Link to="/takeout/123">一品鲜</Link>
            <Link to="/takeout/234">牛肉火锅</Link>
            <Link to="/takeout/456">糖水</Link>
          </div>
          <div className="container">
            <Route path="/takeout/:id" component={Child}></Route>
          </div>
        </Router>

在这里插入图片描述

2.replace: 当设置为 true 时,点击链接后将替换历史堆栈中的当前条目,而不是添加新条目。默认为 false。

3.activeClassName:当元素处于激活状态时应用的类,默认为 active。它将与 className 属性一起使用。(可用于用户点击某路由后,将它设置高亮样式)

4.activeStyle:对象类型,当元素处于激活状态时应用的样式。
5.exact:如果为 true,则只有在位置完全匹配时才应用激活类/样式。

猜你喜欢

转载自blog.csdn.net/weixin_43334673/article/details/111414261