面朝大海,春暖花开
          宫崎骏曾说过一句话:遇见都是天意,拥有的都是幸运,世界上有一千种等待,最好的那种叫“未来可期”

React 路由

React 路由

1.ReactRouter 5.x

功能概述:点击切换展示区内容,并切换浏览器地址 /about /home

About 组件

import React, { Component } from 'react'

export default class About extends Component {
  render() {
    return (
      <h3>
        我是About的内容
      </h3>
    )
  }
}

Home组件

import React, { Component } from 'react'

export default class Home extends Component {
  render() {
    return (
      <h3>
        我是Home的内容
      </h3>
    )
  }
}

React6.x-App.jsx

import React, { Component } from 'react'
import { Link, Route , Routes} from 'react-router-dom'
import About from './components/About'
import Home from './components/Home'

export default class App extends Component {
  render() {
    return (
      <div>
        <div className="row">
          <div className="col-xs-offset-2 col-xs-8">
            <div className="page-header"><h2>React Router Demo</h2></div>
          </div>
        </div>
        <div className="row">
          <div className="col-xs-2 col-xs-offset-2">
            <div className="list-group">
              {/* 点击链接,修改浏览器地址-编写路由链接 */}
              <Link className="list-group-item" to="/about">About</Link>
              <Link className="list-group-item" to="/home">Home</Link>
            </div>
          </div>
          <div className="col-xs-6">
            <div className="panel">
              <div className="panel-body">
                {/* 注册路由 */}
                <Routes>
                  <Route path="/about" element={<About/>} />
                  <Route path="/home" element={<Home/>} />
                </Routes>
                  {/*React5.x 可以直接用 Route 标签,不使用 element 元素*/}
                  {/*
                  	<Route path="/about" component={About} />
                  	<Route path="/home" component={Home} />	
                  */}
              </div>
            </div>
          </div>
        </div>
      </div>
    )
  }
}

2.路由组件和普通组件:

3.Link 标签没有高亮样式,使用 NavLink 就具有高亮样式,可以给 NavLink 添加 activeClassName 属性指定样式

<div className="list-group">
{/* 点击链接,修改浏览器地址-编写路由链接 */}
	<NavLink activeClassName="navactive" className="list-group-item" to="/about">About</NavLink>
	<NavLink activeClassName="navactive" className="list-group-item" to="/home">Home</NavLink>
</div>

然后在 public/index.html 中添加样式

<style>
	.navactive{
		background-color: orange !important;
		color: white !important
	}
</style>

4.如果存在多个 NavLink 标签看起来就很繁琐,我们可以自己封装一个 MyNavLink,下面是部分代码片段

App.js 中修改部分

// 对于通过标签体中传递的值,会自动存储到 children 属性中
<MyNavLink to="/about">About</MyNavLink>
<MyNavLink to="/home">Home</MyNavLink>

新创建的普通组件 MyNavLink

import React, { Component } from 'react'
import { NavLink } from 'react-router-dom'
export default class MyNavLink extends Component {
  render() {
    return (
      <NavLink activeClassName="navactive" className="list-group-item" {...this.props}/>
    )
  }
}

5.如果 Route 特别多的话,我们希望匹配上了就不要继续向下匹配了,我们可以通过 Switch 组件来完成,匹配到对应路径就结束匹配

/*如果不使用 Switch 组件在点击 /home 就会出现两个 Home 组件渲染出来的数据*/
<Switch>
	<Route path="/about" component={About} />
	<Route path="/home" component={Home} />
	<Route path="/home" component={Home} />
</Switch>

6.多级路径解决样式丢失的三种办法

样式是在 index.html 中引入的 <link rel="stylesheet" href="./css/bootstrap.css" type="text/css">

        <div className="row">
          <div className="col-xs-2 col-xs-offset-2">
            <div className="list-group">
              {/* 点击链接,修改浏览器地址-编写路由链接 */}
              <MyNavLink to="/bonbons/about">About</MyNavLink>
              <MyNavLink to="/bonbons/home">Home</MyNavLink>
            </div>
          </div>
          <div className="col-xs-6">
            <div className="panel">
              <div className="panel-body">
                {/* 注册路由 */}
                <Switch>
                  <Route path="/bonbons/about" component={About} />
                  <Route path="/bonbons/home" component={Home} />
                </Switch>

              </div>
            </div>
          </div>
        </div>

点击按钮后刷新,就会找不到样式,返回 index.html 的内容

  • 修改引入样式: <link rel="stylesheet" href="/css/bootstrap.css" type="text/css">【去掉相对路径的点】
  • 修改引入样式:<link rel="stylesheet" href="%PUBLIC_URL%/css/bootstrap.css" type="text/css">【使用public的绝对路径】
  • 修改路由器的类型:
import React from 'react'
import ReactDOM from 'react-dom'
import { HashRouter } from 'react-router-dom'
import App from './App.jsx'

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

7.Link和Route之间默认是模糊匹配

  • 意思就是只要Link从头开始包含Route中的path,那么就可以匹配上
  • 只要不出现问题,我们就不用开启严格匹配,可以通过给 Route 添加属性 exactexact={true} 开启严格匹配

8.使用重定向组件,可以指定默认路径

// 兜底作用
<Switch>
	<Route path="/about" component={About} />
	<Route path="/home" component={Home} />
	<Redirect to="about"/>
</Switch>

9.如果想使用嵌套路由,那么需要子路由以父路由地址开头,而且父路由不能使用严格匹配,因为只有执行到子组件注册路由的部分才能正确匹配到对应的组件

import React, { Component } from 'react'
import { Route, Redirect } from 'react-router-dom'
import MyNavLink from '../../components/MyNavLink'
import Message from './Message'
import News from './News'

export default class Home extends Component {
  render() {
    return (
      <div>
        <h3>
          我是Home的内容
        </h3>
        <div>
          <ul className="nav nav-tabs">
            <li>
              <MyNavLink to="/home/news">News</MyNavLink>

            </li>
            <li>
              <MyNavLink to="/home/message">Message</MyNavLink>
            </li>
          </ul>
          {/* 注册路由 */}
          <Route path="/home/news" component={News} />
          <Route path="/home/message" component={Message} />
          <Redirect to="/home/news" />
        </div>
      </div>

    )
  }
}

10.如何向路由传递参数呢?

我们给 message 添加子组件,显示具体的消息

11.向路由组件传递参数的几种方式

(1)通过 params 参数传递
Detail组件

import React, { Component } from 'react'
const datas = [
    { id: '1', content: '你好,中国' },
    { id: '2', content: '你好,北京' },
    { id: '3', content: '你好,未来' },
]
export default class Detail extends Component {
    render() {
        const { id, title } = this.props.match.params
        const findResult = datas.find((data) => {
            return data.id === id
        })
        return (
            <div>
                <ul>
                    <li>id:{id}</li>
                    <li>title:{title}</li>
                    <li>content:{findResult.content}</li>
                </ul>
            </div>
        )
    }
}

Message组件

import React, { Component } from 'react'
import { Route, Link } from 'react-router-dom'
import Detail from './Detail'

const messages = [
    { id: '1', title: 'message001' },
    { id: '2', title: 'message002' },
    { id: '3', title: 'message003' },
]
export default class Message extends Component {
    render() {
        return (
            <div>
                <ul>
                    {
                        messages.map((msgObj) => {
                            return (
                                <li key={msgObj.id}>
                                    <Link to={`/home/message/detail/${msgObj.id}/${msgObj.title}`}>{msgObj.title}</Link>
                                </li>
                            )
                        })
                    }
                </ul>
                <hr/>
                <Route path="/home/message/detail/:id/:title" component={Detail}/>
            </div>
        )
    }
}

(2)通过 search 参数传递

// Detail 组件中的区别
const {id, title} = qs.parse(this.props.location.search.slice(1))
// Message 组件中的区别
<Link to={`/home/message/detail/?id=${msgObj.id}&title=${msgObj.title}`}>{msgObj.title}</Link>
<Route path="/home/message/detail" component={Detail}/>

(3)通过 state 参数传递

// Detail 组件中的区别
const {id, title} = this.props.location.state
// Message 组件中的区别
<Link to={{pathname:'/home/message/detail', state:{id:msgObj.id, title:msgObj.title}}}>{msgObj.title}</Link>
<Route path="/home/message/detail" component={Detail}/>

12.利用 history 实现编程式路由导航

this.props.history.push(path, state)
this.props.history.replace(path, state)
this.props.history.push(path, state)
this.props.history.goBack()
this.props.history.goForward()
this.props.history.go(n) // n > 0 前进n步, n < 0 后退 n 步

13.使用 withRouter 可以让一般组件使用路由组件的 API

14.HashRouter、BrowserRouter 的区别

posted @ 2023-10-06 21:42  小赵同学爱编码  阅读(19)  评论(0)    收藏  举报