react 11之 router6路由 (两种路由模式、两种路由跳转、两种传参与接收参数、嵌套路由,layout组件、路由懒加载)

react路由1:安装和两种模式

  • npm i react-router-dom
  • 两种模式
    • Router:所有路由组件的根组件,包裹路由的最外层容器
    • Link:跳转路由组件
    • Routes :用于定义和渲染路由规则( 用于替换 Switch 组件)
    • Route:路由规则匹配组件,显示当前规则对应的组件
      • exact => 精确匹配,只有当 path 和 pathname 完全匹配时才会展示该路由
import React from 'react';
// import { BrowserRouter as Router, Link, Route, Routes } from 'react-router-dom';
import {
    
     HashRouter as Router, Link, Route, Routes } from 'react-router-dom';

const Home = () => <h1>Home</h1>;
const About = () => <h1>About</h1>;

const App = () => {
    
    
  return (
    <Router>
      <nav>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
        </ul>
      </nav>

      <Routes>
        <Route path="/" element={
    
    <Home />} />
        <Route path="/about" element={
    
    <About />} />
      </Routes>
    </Router>
  );
};

export default App;

react路由2:两种路由跳转 ( 命令式与编程式)

2-1 路由跳转-命令式

import React from 'react';
// import { BrowserRouter as Router, Link, Route, Routes } from 'react-router-dom';
import {
    
     HashRouter as Router, Link, Route, Routes } from 'react-router-dom';

const Home = () => <h1>Home</h1>;
const About = () => <h1>About</h1>;

const App = () => {
    
    
  return (
    <Router>
      <nav>
        <ul>
          <li>
            <Link to="/">Home</Link>
          </li>
          <li>
            <Link to="/about">About</Link>
          </li>
        </ul>
      </nav>
      <Routes>
        <Route path="/" element={
    
    <Home />} />
        <Route path="/about" element={
    
    <About />} />
      </Routes>
    </Router>
  );
};

export default App;

2-2 路由跳转-编程式 - 函数组件

2-2-1 app.jsx

import React, {
    
     Component } from 'react';
import {
    
     HashRouter as Router, Route, Routes } from 'react-router-dom';
import About from "./page/About";
import Home from "./page/Home";
export default class App extends Component {
    
    
 state = {
    
    
 }
 render(){
    
    
   return (
    <Router>
      <Routes>
        <Route path="/" element={
    
     <Home />} />
        <Route path="/about" element={
    
     <About />} />
      </Routes>
    </Router>
   )
 }
}

2-2-2 page / Home.jsx


import React from 'react';
import {
    
     useNavigate } from 'react-router-dom';
const Home = () => {
    
    
  const navigate = useNavigate();
  const goToAbout = () => {
    
    
    navigate('/about');
  }
  return (
    <div>
      <h1>Home</h1>
      <button onClick={
    
    goToAbout}>Go to About</button>
    </div>
  )
}
export default Home;

2-2-3 page / About.jsx


import React from 'react';
import {
    
     useNavigate } from 'react-router-dom';
const About = () => {
    
    
  const navigate = useNavigate();
  const goToAbout = () => {
    
    
    navigate('/');
  }
  return (
    <div>
      <h1>About</h1>
      <button onClick={
    
    goToAbout}>Go to Home</button>
    </div>
  )
}
export default About;

2-2-4 效果

在这里插入图片描述

react路由3:函数式组件-编程式导航传递参数

3-1 app.jsx

import React, {
    
     Component } from 'react';
import {
    
     HashRouter as Router, Route, Routes } from 'react-router-dom';
import About from "./page/About";
import Home from "./page/Home";
export default class App extends Component {
    
    
 state = {
    
    
 }
 render(){
    
    
   return (
    <Router>
      <Routes>
        <Route path="/" element={
    
    <Home/>} />
        {
    
    /* 精确匹配:只有当 path 和 pathname 完全匹配时才会展示该路由 */}
        <Route exact path="/about" element={
    
     <About/> } />
      </Routes>
    </Router>
   )
 }
}

3-2 Home.jsx


import React from 'react';
import {
    
     useNavigate } from 'react-router-dom';
const Home = () => {
    
    
  const navigate = useNavigate();
  const goToAbout = () => {
    
    
    // 向about页面 01:传递search参数数据,拼接再url中=> /about?name=homeName ; 02:传递state=> 自定义数据
    navigate('/about?name=homeName&code=001',{
    
     state: {
    
    key:'来自home传递'} });
  }
  return (
    <div>
      <p>Home</p>
      <button onClick={
    
    goToAbout}>Go to About</button>
    </div>
  )
}
export default Home;

3-3 About.jsx


import React from 'react';
import {
    
     useLocation, useNavigate } from 'react-router-dom';
const About = () => {
    
    
  const navigate = useNavigate();
  const location = useLocation();
  // 当前about页面 接受 home页面传递的参数
  console.log('location',location,"location.state",location.state); // location.state {key: '来自home传递'}
  const searchParams = new URLSearchParams(location.search);
  const param1 = searchParams.get('name');
  const param2 = searchParams.get('code');
  console.log('param1',param1,'param2',param2); // param1 homeName param2 001

  const goToAbout = () => {
    
    
    navigate('/');
  }
  return (
    <div>
      <p>About - key {
    
    location.state.key} </p>
      <button onClick={
    
    goToAbout}>Go to Home</button>
    </div>
  )
}
export default About;

react路由4:路由重定向

  • 使用 Navigate 组件实现重定向 , 匹配到 path="*" 需要放置再最后一个

app.jsx

  • <Route path="*" element={<Navigate to="/" />} />
import React, {
    
     Component } from 'react';
import {
    
     HashRouter as Router, Navigate, Route, Routes } from 'react-router-dom';
import About from "./page/About";
import Home from "./page/Home";
import Test from "./page/Test";
export default class App extends Component {
    
    
 state = {
    
    
 }
 render(){
    
    
   return (
    <Router>
      <Routes>
        <Route path="/" element={
    
    <Home/>} />
        {
    
    /* 精确匹配:只有当 path 和 pathname 完全匹配时才会展示该路由 */}
        <Route exact path="/about" element={
    
     <About/> } />
        <Route exact path="/test" element={
    
     <Test/> } />
        <Route path="*"  element={
    
    <Navigate to="/" />} />
      </Routes>
    </Router>
   )
 }
}

react路由5:嵌套路由,layout组件、路由懒加载

index.jsx 入口文件

import React from 'react';
import ReactDOM from 'react-dom/client';
import {
    
     Provider } from 'react-redux';
import App from "./App";
import store from "./store/index.js";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
    <Provider store={
    
    store}>
        <App />
    </Provider>
);

app.js 和 app.css

import React, {
    
     Suspense } from "react";
import {
    
     HashRouter as Router, Navigate, Route, Routes } from 'react-router-dom';
import "./app.css";
import routes from "./router/index";
const renderRoutes = (routes) => {
    
    
  return routes.map((route, index) => {
    
    
    const {
    
     path, element, children } = route;
    return (
      <Route
        key={
    
    index}
        path={
    
    path}
        element={
    
    element}
      >
        <Route index element={
    
    <Navigate to="/home" replace />} />
        {
    
    children && renderRoutes(children)}
      </Route>
    );
  });
};

export default function App() {
    
    
  return (
    <div id="app">
      <Router>
        <Suspense  fallback={
    
    <div>Loading...</div>}>
          <Routes>
            {
    
    renderRoutes(routes)}
            <Route path="*"  element={
    
    <Navigate to="/home" />} />
          </Routes>
        </Suspense>
      </Router>
    </div>
  );
}

* {
    
    
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}
html,body,#root,#app{
    
    
  height: 100vh;
}
body {
    
    
  font-family: sans-serif;
  overflow: hidden;
}

router / index.js

import {
    
     lazy } from "react";
import {
    
     Navigate } from "react-router-dom";
const Layout = lazy(() => import("../5react路由/page/Layout"))
const Home = lazy(() => import("../5react路由/page/Home"))
const About = lazy(() => import('../5react路由/page/About'))
const Test = lazy(() => import("../5react路由/page/Test"))
const News = lazy(() => import("../5react路由/page/Form/News"))
const Form = lazy(() => import("../5react路由/page/Form/Form"))
const routes = [
  {
    
    
    path:"/",
    element: <Layout />,
    children:[
      {
    
     // 用于重定向到 home page
      	index: true,
      	element: <Navigate to="/home" replace />
	    },
      {
    
    
        path: 'home',
        element: <Home/>
      },
      {
    
    
        path: 'about',
        element: <About/>,
        exact:true ,// 精准匹配
      },
      {
    
    
        path: 'test',
        element: <Test/>,
        exact:true // 精准匹配
      }
    ]
  },
  {
    
    
    path: 'form',
    element: <Form/>,
    // exact:true ,// 精准匹配
    children: [
      {
    
    
        index: true,
        element: <Navigate to="/form/news" replace />
      },
      {
    
    
        path: 'news',
        element: <News/>,
      }
    ]
  },
]

export default routes

page / layout.jsx h5的layout组件

import React from 'react';
import {
    
     Outlet, useNavigate } from 'react-router-dom';
import styled from 'styled-components';
const footerList = [
  {
    
     path:"/home",name:'首页',key:'home' },
  {
    
     path:"/about",name:'关于',key:'about' },
  {
    
     path:"/test",name:'测试',key:'test' }
]
const AppWrap = styled.div`
  background: #eee;
  height: 100vh;
  .header {
    height: 32px;
    line-height: 32px;
    background: #ddd;
  }
  .main {
    margin-bottom:32px;
    background: #eee;
    height: calc(100% - 64px);
  }
  .footer {
    position: fixed;
    bottom:0;
    left:0;
    width:100%;
    display: flex;
    justify-content: center;
    align-items: center;
    .footer-item {
      height: 32px;
      line-height: 32px;
      color: #fff;
      flex: 1;
      text-align: center;
      background: #ccc;
    }
  }
`;
export default function Layout(props) {
    
    
  const navigate = useNavigate()
  const goToPage = (item) => {
    
    
    console.log('goToPage', item.path);
    navigate(item.path)
  }
  return (
    <AppWrap>
        <div className='header'>header</div>
        <div className='main'><Outlet/></div>
        <div className='footer'>
          {
    
    
            footerList.map(item => {
    
    
              return (
                <div className='footer-item' key={
    
    item.key} onClick={
    
    ()=>{
    
    goToPage(item)}}>{
    
    item.name}</div>
              )
            })
          }
        </div>
    </AppWrap>
  )
}

page / Home.jsx


import React from 'react';
const Home = () => {
    
    
  return (
    <div>
        <p>home首页Home</p>
    </div>
  )
}
export default Home;

page / About.jsx


import React from 'react';
import {
    
     useNavigate } from 'react-router-dom';
const About = () => {
    
    
  const navigate = useNavigate();
  const goToForm = () =>{
    
    
    navigate('/form');
  }
  return (
    <div>
      <p>About</p>
      <button onClick={
    
    goToForm}>Go to form</button>
    </div>
  )
}
export default About;

page / Test.jsx


import React from 'react';
import {
    
     useNavigate } from 'react-router-dom';
const Test = () => {
    
    
  const navigate = useNavigate();
  const goToReset = () =>{
    
    
    navigate('/aaaa');
  }
  const goToNews = () =>{
    
    
    navigate('/form/news');
  }
  return (
    <div>
      <p>Test</p>
      <button onClick={
    
    goToReset}>Go to 重定向</button>
      <button onClick={
    
    goToNews}>Go to News</button>
    </div>
  )
}
export default Test;

page / form / form.jsx 使用Outlet 渲染子路由


import React from 'react';
import {
    
     Outlet, useNavigate } from 'react-router-dom';
const Form = () => {
    
    
  const navigate = useNavigate();
  const goToHome = () =>{
    
    
    navigate('/home');
  }
  return (
    <div>
      <Outlet />
      <button onClick={
    
    goToHome}>Go to Home</button>
    </div>
  )
}
export default Form;

page / form / News/jsx


import React from 'react';
import {
    
     useNavigate } from 'react-router-dom';
const News = () => {
    
    
  const navigate = useNavigate();
  const goToReset = () =>{
    
    
    navigate('/bbb');
  }
  return (
    <div>
      <p>News</p>
      <button onClick={
    
    goToReset}>Go to 重定向</button>
    </div>
  )
}
export default News;

效果

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_43845137/article/details/132302946