0
点赞
收藏
分享

微信扫一扫

React 之Router路由(含5.0与6.0版本)

Soy丶sauce 2022-04-19 阅读 61

目录

一、介绍

二、事前准备

2.1 安装路由模块

2.2  相关组件 

三、V5版本路由使用

3.1  声明式导航

3.2  编程式导航

3.3  嵌套路由

3.4  路由传参

3.4.1   动态路由参数(param)

3.4.2 查询字符串(query)

3.4.3  隐式传参(state)

3.5  重定向 与 404

3.6   三种路由的渲染方式【了解】

3.6.1  component= (组件对象或者函数)

3.6.2   render 函数

3.6.3   children(函数或者组件)

3.7  withRouter高阶组件

3.8  自定义导航组件

四、V6版本路由使用

4.1  声明式导航

4.2  编程式导航

4.3  重定向与404

4.3.1  重定向

4.3.2  404  

4.4  传参

4.4.1  query传参

4.4.2   params传参

4.4.3   state传参

​4.5  嵌套路由

 4.6  批量配置路由


一、介绍

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

Ø 前端路由功能:让用户从一个视图(组件)导航到另一个视图(组件)

Ø 前端路由是一套映射规则,在React中,是URL路径与组件的对应关系

Ø 使用React路由简单来说,就是配置路径和组件

注意:2021年11月路由依赖包react-router-dom开启v6版本,注意新api的变化

在介绍完v5.0稳定版以后,会在文章后面介绍v6.0版本的改动以及案例演示。 

二、事前准备

2.1 安装路由模块

2.2  相关组件 

三、V5版本路由使用

3.1  声明式导航

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

代码展示:

import React, { Component } from 'react';
// 引入相关组件
import { Link,Route,Switch,NavLink } from 'react-router-dom'
// 引入类组件
import Home from './pages/Home';
import User from './pages/User';

class App extends Component {
    render() {
        return (
            <>
            {/* 声明式导航 */}
            
               < NavLink to={"/home"} >home页面</NavLink>
               < NavLink to={"/user"}>user页面</NavLink>

               <Switch>
               <Route path={"/home"} component = { Home }></Route>
               <Route path={"/user"} component = { User }></Route>
               </Switch>
            </>
        );
    }
}

export default App;

运行结果:

3.2  编程式导航

通过与react-router-dom中withRouter与history对象中的push/replace/go等方法搭配使用实现编程式导航功能。

这里需要注意,引入whitRouter,用于解决this.props.history 拿不到值的问题。

import React, { Component } from 'react';
// 引入相关组件
import { Link,Route,Switch,NavLink } from 'react-router-dom'
// 引入类组件
import Home from './pages/Home';
import User from './pages/User';
// 引入withRouter来解决 this.props.history 拿不到值的问题
import { withRouter } from 'react-router-dom'
@withRouter
class App extends Component {
    homeHander = () =>{
       console.log(this.props.history); 
       this.props.history.push("/home")
    }
    userHander = () =>{
        console.log(this.props.history); 
        this.props.history.push("/user")
     }
    render() {
        return (
            <>
            {/* 编程式导航 */}
               <a onClick={this.homeHander}>home界面</a>
               <a onClick={this.userHander}>user界面</a>
               <Switch>
               <Route path={"/home"} component = { Home }></Route>
               <Route path={"/user"} component = { User }></Route>
               </Switch>
            </>
        );
    }
}

export default App;

3.3  嵌套路由

3.4  路由传参

3.4.1   动态路由参数(param)

通过this.props.match.params拿值

运行结果:

3.4.2 查询字符串(query)

通过 this.props.location.search 拿值

运行结果: 

3.4.3  隐式传参(state)

这里注意,传过去的参数刷新会消失

通过this.props.location.state拿state的值

通过this.props.history.location.params拿params的值

运行结果: 

3.5  重定向 与 404

3.6   三种路由的渲染方式【了解】

3.6.1  component= (组件对象或者函数)

3.6.2   render 函数

3.6.3   children(函数或者组件)

3.6.4  3种渲染区别总结

  • component可以使用组件类渲染或内联式方式渲染,render只能使用函数,children使用函数或直接使用组件对象

  • component内联式渲染方式在每次匹配路由成功后都将创建一个新组件,而后两者不会,所以用内联式方式建议使用后两者,内联方式渲染组件,推荐用render

  • 当children的值是一个函数时,无论当前地址和path路径匹不匹配,都将会执行children对应的函数,当children的值为一个组件时,当前地址和path不匹配时,路由组件不渲染

  • children函数方式渲染,会在形参中接受到一个对象,对象中match属性如果当前地址匹配成功返回对象,否则null

3.7  withRouter高阶组件

import {
    useLocation,
    useNavigate, 
    useParams
  } from "react-router-dom";
//   useNavigate  用来跳转用的  函数组件使用  useLocation接收参数用 useParams接收参数
  export function withRouter(Component) {
    function ComponentWithRouterProp(props) {
      let location = useLocation();
      let navigate = useNavigate();
      let params = useParams();
      return (
        <Component
          {...props}
          router={{ location, navigate, params }}
        />
      );
    }
  
    return ComponentWithRouterProp;
  }

3.8  自定义导航组件

import React, { Component } from 'react';
// 引入相关组件
import { Link,Route,Switch,NavLink } from 'react-router-dom'
// 引入函数组件
import Home from './pages/Home';
import User from './pages/User';
// 引入自定义导航组件
import Mylink from './pages/Mylink';
class App extends Component {
    render() {
        return (
            <>
            {/* 传参 */}
            
               < NavLink to="/home" >home页面</NavLink>
               < NavLink to="/user">user页面</NavLink>
               {/* 引入自定义导航组件 */}
               <Mylink to="/home" tag = 'p'>首页</Mylink>
               <Mylink to="/user"tag = 'p'>用户页</Mylink>

               <Switch>
               <Route path="/user"  component = { Home }></Route>
               <Route path="/user" component = { User }></Route>
               </Switch>
            </>
        );
    }
}

export default App;

   自定义路由组件  公共组件

import React from 'react';
import { Route , withRouter } from 'react-router-dom'

const Mylink = (props) => {
    const handerClick = () => {
        props.history.push(props.to)
    }
    const Tag = props.tag
    const to = props.to

    return (
      // match 使用函数组件 类组件match获取不到最新匹配的值
             <Route path={to} children={({match})=>{
               console.log('match',match);
              if(match){
                   return <Tag style={{color:'red'}} onClick={ handerClick }
                  >{ props.children }</Tag>
              }
              return <Tag  onClick={handerClick}
                  >{ props.children }</Tag>
            }} />
    );
}

export default withRouter(Mylink);

运行结果:

四、V6版本路由使用

4.1  声明式导航

三个改动:

  1. swicth替换为 Routes

  2. comopnent替换为 element

  3. element里以前是直接放User 现在是<User/>

import React, { Component } from 'react';
import { Route, Routes, Link, useNavigate } from 'react-router-dom'
import User from './pages/User';
import Home from './pages/Home';
class App extends Component {
    render() {
        return (
            <>
                {/* swicth替换为 Routes */}
                <Routes>
                    {/* comopnent替换为 element */}
                    <Route path='/home' element={<Home />}></Route>
                    {/* 以前是直接放User 现在是<User/> */}
                    <Route path='/user' element={<User />}></Route>
                </Routes>
                <Link to={'/home'}>首页</Link>
                <Link to={'/user'}>用户</Link>
            </>
        );
    }
}

export default App;

4.2  编程式导航

通过this.props.router.navigate进行路径更改

需要注意的是V6版本中,删除了withRouter,所以需要自己封装,并引入

WithRouter代码如下:

import {
    useLocation,
    useNavigate, 
    useParams
  } from "react-router-dom";
//   useNavigate  用来跳转用的  函数组件使用  useLocation接收参数用 useParams接收参数
  export function withRouter(Component) {
    function ComponentWithRouterProp(props) {
      let location = useLocation();
      let navigate = useNavigate();
      let params = useParams();
      return (
        <Component
          {...props}
          router={{ location, navigate, params }}
        />
      );
    }
  
    return ComponentWithRouterProp;
  }

代码展示: 

import React, { Component } from 'react';
import { Route, Routes, Link, useNavigate } from 'react-router-dom'
import User from './pages/User';
import Home from './pages/Home';
// 需要自己封装 V6版本删除了withRouter
import  {withRouter}  from './pages/WithRouter';

class App extends Component {
    hander = ()=>{
        
        console.log(this.props);

        this.props.router.navigate('/home')
    }
    handers = ()=>{
        console.log(this.props);
        this.props.router.navigate('/user')
    }
    render() {
        return (
            <>
                {/* swicth替换为 Routes */}
                <Routes>
                    {/* comopnent替换为 element */}
                    <Route path='/home' element={<Home />}></Route>
                    {/* 以前是直接放User 现在是<User/> */}
                    <Route path='/user' element={<User />}></Route>
                    
                </Routes>

                <Link to={'/home'}>首页</Link>
                <Link to={'/user'}>用户</Link>
                {/* 编程式导航 */}
                <button onClick={this.hander}>首页</button>
                <button onClick={this.handers}>用户</button>

            </>
        );
    }
}

export default withRouter(App);

运行结果:

4.3  重定向与404

4.3.1  重定向

先引入navigate

import { Route, Routes, Link, useNavigate,Navigate } from 'react-router-dom'

使用

<Route index element={ <Navigate to="/home "/>}/>

4.3.2  404  

<Route path= "*" element={ <NotFind />} />

4.4  传参

4.4.1  query传参

this.props.router.location.search 接收参数

this.props.router.navigate('/home?name=xzl')

4.4.2   params传参

this.props.router.params  接收参数

this.props.router.navigate('/user/12345')   传参
<Route path='/user/:id' element={<User />}></Route>   路由更改

4.4.3   state传参

注意:V6中state传参只能用于函数组件,类组件不可用

先引入 

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

再赋值

var localtion = useLocation()

最后通过 localtion.state 接收参数。

4.5  嵌套路由

方法一:

<Routes>
{/* 注意带*号表示下面有路由匹配 */}
    <Route path='/home/*' element={<Home />}>
       {/* 二级路由不带  /   */}
        <Route path='Footer' element={<Footer />}></Route>
        <Route path='Header' element={<Header />}></Route>
            </Route>
     <Route path='/user' element={<User />}></Route>
 </Routes>

注意这里需要在二级路由页面有类似于vue路由占位符一样的东西。

方法二:

 4.6  批量配置路由

import React from 'react'
import { useRoutes } from 'react-router-dom'
import Home from './pages/Home'
import User from './pages/User'
import NotFind from './pages/NotFind'
import MyHeader from './pages/MyHeader'
import MyFooter from './pages/MyFooter'

export default function App() {
    //useRoutes   //use开头的函数 统称hooks 函数组件专用  v6常用编程了函数组件
    var ele = useRoutes([
        { 
            path:'/home',
            element: <Home />,
            children:[
                {path:'myheader',element: <MyHeader /> },
                {path:'myfooter',element: <MyFooter /> },
            ]
        },
        { path:'/user',element: <User />},
        { path:'*',element: <NotFind />},
    ])
  return (
    <div>
        <h3>useRoutes案例</h3>
        { ele }
    </div>
  )
}
举报

相关推荐

0 条评论