欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

React中項(xiàng)目路由配置與跳轉(zhuǎn)方法詳解

 更新時(shí)間:2023年08月09日 11:30:38   作者:寄給江南  
這篇文章主要為大家詳細(xì)介紹了React中項(xiàng)目路由配置與跳轉(zhuǎn)方法的相關(guān)資料,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解一下

最近使用 ReactTS 搭建了一個(gè)項(xiàng)目,組件庫(kù)使用的是 Antd5

在配置路由的過(guò)程中出現(xiàn)了一些小問(wèn)題,所以記錄一下這個(gè)過(guò)程。

路由配置集中管理

首先,安裝 react-router-dom 包:

npm i react-router-dom

main.tsx 中,引入 BrowserRouter 并包裹在 App 組件外層:

import ReactDOM from 'react-dom/client';
import { BrowserRouter } from "react-router-dom";
import App from './App.tsx';
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
  <BrowserRouter>
    <App />
  </BrowserRouter>
);

接下來(lái),在 src/routes 目錄下創(chuàng)建 index.tsx 文件,引入所需依賴,并將組件映射到對(duì)應(yīng)路由上,讓 Router 知道在哪里渲染它們,如下:

import { lazy } from "react";
import { Outlet } from 'react-router-dom';
export interface RouteType {
  path: string;
  element: React.ReactNode;
  children?: Array<RouteType>;
}
const Index = lazy(() => import('@/views/Index/index'));
const Information = lazy(() => import('@/views/personal/Information/index'));
const Contacts = lazy(() => import('@/views/personal/Contacts/index'));
const routes: Array<RouteType> = [
  {
    path: '/index',
    element: <Index />,
  }
  {
    path: '/personal',
    element: <><Outlet></>,
    children: [
      {
        path: 'information',
        element: <Information />
      },
      {
        path: 'contacts',
        element: <Contacts />
      }
    ]
  }
];
export default routes;

在上述代碼中,使用 React.lazy() 方法實(shí)現(xiàn)路由組件懶加載。

路由懶加載就是把不同的路由組件分割成不同的代碼塊,只有在路由被訪問(wèn)的時(shí)候,才會(huì)加載對(duì)應(yīng)組件,其實(shí)就是按需加載。使用方法如下:

() => import(`@/views/${component}`)

如果在某個(gè)路由下有子路由,通過(guò) children 屬性配置,就是上面代碼中的這段:

const routes: Array<RouteType> = [
  // ...
  {
    path: '/personal',
    element: <><Outlet></>,
    children: [
      {
        path: 'information',
        element: <Information />
      },
      {
        path: 'contacts',
        element: <Contacts />
      }
    ]
  }
];

其中,我們需要在渲染子組件的位置使用 Outlet 組件占位,當(dāng)然也可以使用 useOutlet(),它會(huì)返回該路由組件的子路由元素。

由于我使用 Fragment 作為子組件的容器,所以直接把 Outlet 放在這里占位。

一般情況下,父組件中還會(huì)有其他元素,此時(shí)我們需要這樣設(shè)置:

import { Outlet } from 'react-router-dom';
export const Information = () => {
  return (
    <Content>
      // ...
      <Outlet /> // 子組件渲染出口
    </Content>
  )
}

最后,使用 useRoutes() 動(dòng)態(tài)配置路由。

useRoutes() 是 React Router V6 的一個(gè) Hook,它接收一個(gè)路由數(shù)組(也就是 routes 數(shù)組),根據(jù)匹配到的路由渲染相應(yīng)的組件。

import { useRoutes } from 'react-router-dom'; // 引入 useRoutes
// ...
const WrappedRoutes = () => {
  return useRoutes(routes);
};
export default WrappedRoutes;

到此,路由的集中管理就配置完畢。我們?cè)?app.tsx 文件中引入 WrapperRoutes 就可以使用了。

import WrappedRoutes from '@/router/index';
const App: React.FC = () => {
  return (
    <Layout style={{ minHeight: '100vh' }}>
      <Sider>
        <div style={{ height: 90 }} />
        <Menu />  // 側(cè)邊導(dǎo)航欄
      </Sider>
      <Layout>
        <Content style={{ margin: 16 }}>
          <WrappedRoutes /> // 渲染路由組件的位置
        </Content>
      </Layout>
    </Layout>
  )
};

/routes/index.tsx 完整代碼如下:

import { lazy } from "react";
import { Outlet, useRoutes } from 'react-router-dom';
export interface RouteType {
  path: string;
  element: React.ReactNode;
  children?: Array<RouteType>;
}
const Index = lazy(() => import('@/views/Index/index'));
const Information = lazy(() => import('@/views/personal/Information/index'));
const Contacts = lazy(() => import('@/views/personal/Contacts/index'));
const routes: Array<RouteType> = [
  {
    path: '/index',
    element: <Index />,
  }
  {
    path: '/personal',
    element: <><Outlet></>,
    children: [
      {
        path: 'information',
        element: <Information />
      },
      {
        path: 'contacts',
        element: <Contacts />
      }
    ]
  }
];
const WrappedRoutes = () => {
  return useRoutes(routes);
};
export default WrappedRoutes;

如果不使用 useRoutes(),上述功能使用 RoutesRoute 也可以實(shí)現(xiàn):

import { lazy } from "react";
import { Routes, Route, Navigate, Outlet } from 'react-router-dom';
const Index = lazy(() => import('@/views/Index/index'));
const Information = lazy(() => import('@/views/personal/Information/index'));
const Contacts = lazy(() => import('@/views/personal/Contacts/index'));
// ...
const App: React.FC = () => {
  return (
    <Layout style={{ minHeight: '100vh' }}>
      <Sider>
        <div style={{ height: 90 }} />
        <Menu />  // 側(cè)邊導(dǎo)航欄
      </Sider>
      <Layout>
        <Content style={{ margin: 16 }}>
          // 渲染路由組件的位置,用 Routes 包裹
          <Routes>
            <Route path="/" element={<Navigate to="/index" />} />
            <Route path="index" element={<Index />} />
            <Route path="personal" element={<><Outlet /></>} >
              <Route path="information" element={<Information />} />
              <Route path="contacts" element={<Contacts />} />
            </Route>
          </Routes>
        </Content>
      </Layout>
    </Layout>
  )
}

注意:V6 中的嵌套路由可以只定義相對(duì)父路由的相對(duì)路徑,內(nèi)部會(huì)為我們自動(dòng)拼接全路徑。

Menu 組件實(shí)現(xiàn)路由跳轉(zhuǎn)

導(dǎo)航菜單使用的是 Menu 組件。

首先,定義一個(gè)類型為 Array<MenuItem>menuList,用于導(dǎo)航菜單的展示。

// ...
import WrappedRoutes from '@/router/index'; // 引入路由表
type MenuItem = {
  label: string,
  key: string,
  icon?: React.ReactNode
  children?: Array<MenuItem>
}
const menuList: Array<MenuItem> = [{
  label: "首頁(yè)",
  key: "/index",
  icon: <PieChartOutlined rev={undefined} />,
}, {
  label: "個(gè)人辦公",
  key: "/personal",
  icon: <PushpinOutlined rev={undefined} />,
  children: [
    {
      label: "個(gè)人信息",
      icon: <IdcardOutlined rev={undefined} />,
      key: "/personal/information"
    },
    {
      label: "通訊錄",
      icon: <ContactsOutlined rev={undefined} />,
      key: "/personal/contacts"
    }
  ]
}]
const App: React.FC = () => {
  return (
    <Layout style={{ minHeight: '100vh' }}>
      <Sider>
        <div style={{ height: 90 }} />
        <Menu theme="dark" mode="inline" items={menuList} />
      </Sider>
      <Layout>
        <Content style={{ margin: 16 }}>
          <WrappedRoutes />
        </Content>
      </Layout>
    </Layout>
  )
};
export default App;

此時(shí)點(diǎn)擊菜單項(xiàng)不能跳轉(zhuǎn)到對(duì)應(yīng)的路由,怎么實(shí)現(xiàn)呢?

在 Menu 組件上可以綁定點(diǎn)擊事件,通過(guò)它可以獲取 key、keyPath 等屬性。

const App = () => {
  const handleClick = (e: any) => {
    console.log(e);
    console.log('key', e.key);
  }
  return (
    // ...
    <Menu theme="dark" mode="inline" items={menuList} onClick={handleClick} />
  )
}

點(diǎn)擊 “個(gè)人信息” 菜單項(xiàng),可以看到,key 屬性就是我們要跳轉(zhuǎn)到的路由組件對(duì)應(yīng)的 url。

接下來(lái),我們?cè)?handleClick 函數(shù)中使用 useNavigate(),將當(dāng)前 event 對(duì)象的 key 屬性傳入,即可根據(jù)傳入的 url 實(shí)現(xiàn)路由跳轉(zhuǎn)。

同時(shí),為了在全局環(huán)境下保持當(dāng)前選項(xiàng)的激活狀態(tài),需要使用 useLocation() 實(shí)時(shí)獲取并保存當(dāng)前 url,并交給 Menu 組件的 selectedKeys 屬性,它就是用于保存當(dāng)前激活的菜單選項(xiàng)。

import { useLocation, useNavigate } from 'react-router-dom';
const App = () => {
  const navigate = useNavigate();
  const { pathname } = useLocation(); // 獲取當(dāng)前url
  const handleClick = (e: any) => {
    navigate(e.key); // 實(shí)現(xiàn)跳轉(zhuǎn)
  }
  return (
    // ...
    <Menu theme="dark" selectedKeys={[pathname]} mode="inline" 
      items={menuList} onClick={handleClick} />
  )
}

除去組件庫(kù)的引入,這部分功能的完整代碼如下:

import WrappedRoutes from '@/router/index'; // 引入路由表
import { useLocation, useNavigate } from 'react-router-dom';
type MenuItem = {
  label: string,
  key: string,
  icon?: React.ReactNode
  children?: Array<MenuItem>
}
const menuList: Array<MenuItem> = [{
  label: "首頁(yè)",
  key: "/index",
  icon: <PieChartOutlined rev={undefined} />,
}, {
  label: "個(gè)人辦公",
  key: "/personal",
  icon: <PushpinOutlined rev={undefined} />,
  children: [
    {
      label: "個(gè)人信息",
      icon: <IdcardOutlined rev={undefined} />,
      key: "/personal/information"
    },
    {
      label: "通訊錄",
      icon: <ContactsOutlined rev={undefined} />,
      key: "/personal/contacts"
    }
  ]
}]
const App: React.FC = () => {
  const navigate = useNavigate();
  const { pathname } = useLocation(); // 獲取當(dāng)前url
  const handleClick = (e: any) => {
    // console.log(e);
    // console.log('key', e.key);
    navigate(e.key); // 實(shí)現(xiàn)跳轉(zhuǎn)
  }
  return (
    <Layout style={{ minHeight: '100vh' }}>
      <Sider>
        <div style={{ height: 90 }} />
        <Menu theme="dark" selectedKeys={[pathname]} mode="inline" 
          items={menuList} onClick={handleClick} />
      </Sider>
      <Layout>
        <Content style={{ margin: 16 }}>
          <WrappedRoutes />
        </Content>
      </Layout>
    </Layout>
  )
};
export default App;

Breadcrumb 組件動(dòng)態(tài)切換

首先,根據(jù)上面配置的 menuList 實(shí)現(xiàn)一個(gè) getBreadcrumbNameMap 函數(shù),生成 keylabel 的映射關(guān)系。

export const breadcrumbMap: Map<string, string> = new Map();
// 因?yàn)樽勇酚勺疃嘀挥幸粚?,使用雙循環(huán)簡(jiǎn)單實(shí)現(xiàn)功能。
function getBreadcrumbNameMap(breadcrumbMap: Map<string, string>) {
  for (let menuItem of menuList) {
    breadcrumbMap.set(menuItem.key, menuItem.label);
    if (menuItem.children) {
      for (let child of menuItem.children) {
        breadcrumbMap.set(child.key, child.label);
      }
    }
  }
}
console.log(breadcrumbMap);

我們已經(jīng)使用 useLocation 保存了當(dāng)前路由組件對(duì)應(yīng)的 url,也就是 pathname。

將得到的 pathname/ 字符分割并逐節(jié)遍歷,在 breadcrumbMap 中尋找對(duì)應(yīng)的 label,找到了就拼接下一段,繼續(xù)在 breadcrumbMap 中匹配 label,以此類推,直到遍歷完成。

const App = () => {
  const { pathname } = useLocation();
  const pathSnippets = pathname.split('/').filter((i) => i);
  const breadcrumbItems = pathSnippets.map((_, index) => {
    const url = `/${pathSnippets.slice(0, index + 1).join('/')}`;
    console.log(url);
    return {
      key: url,
      title: <Link to={url}>{breadcrumbMap.get(url)}</Link>,
    };
  });
  return (
    // ...
    <Content style={{ margin: 16, padding: 12, minHeight: '95vh', backgroundColor: '#fff' }}>
      <Breadcrumb style={{ marginBottom: 20 }} separator="/" items={breadcrumbItems} />
      <WrappedRoutes />
    </Content>
  )
}

最后即可成功獲取當(dāng)前路由對(duì)應(yīng)的面包屑導(dǎo)航,效果如上。

以上就是React中項(xiàng)目路由配置與跳轉(zhuǎn)方法詳解的詳細(xì)內(nèi)容,更多關(guān)于React路由配置的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • React中redux的使用詳解

    React中redux的使用詳解

    Redux 是一個(gè)狀態(tài)管理庫(kù),它可以幫助你管理應(yīng)用程序中的所有狀態(tài),Redux的核心概念之一是Store,它表示整個(gè)應(yīng)用程序的狀態(tài),這篇文章給大家介紹React中redux的使用,感興趣的朋友一起看看吧
    2023-12-12
  • 一文掌握React?組件樹(shù)遍歷技巧

    一文掌握React?組件樹(shù)遍歷技巧

    這篇文章主要為大家介紹了React?組件樹(shù)遍歷技巧的掌握,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • 使用webpack5從0到1搭建一個(gè)react項(xiàng)目的實(shí)現(xiàn)步驟

    使用webpack5從0到1搭建一個(gè)react項(xiàng)目的實(shí)現(xiàn)步驟

    這篇文章主要介紹了使用webpack5從0到1搭建一個(gè)react項(xiàng)目的實(shí)現(xiàn)步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • React高級(jí)指引之Refs and the DOM使用時(shí)機(jī)詳解

    React高級(jí)指引之Refs and the DOM使用時(shí)機(jī)詳解

    在典型的React數(shù)據(jù)流中,props是父組件與子組件交互的唯一方式。要修改一個(gè)子組件,你需要使用新的props來(lái)重新渲染它。但是,在某些情況下,你需要在典型數(shù)據(jù)流之外強(qiáng)制修改子組件
    2023-02-02
  • React高階組件使用教程詳解

    React高階組件使用教程詳解

    高階組件就是接受一個(gè)組件作為參數(shù)并返回一個(gè)新組件(功能增強(qiáng)的組件)的函數(shù)。這里需要注意高階組件是一個(gè)函數(shù),并不是組件,這一點(diǎn)一定要注意,本文給大家分享React 高階組件HOC使用小結(jié),一起看看吧
    2022-12-12
  • React Fiber源碼深入分析

    React Fiber源碼深入分析

    Fiber 可以理解為一個(gè)執(zhí)行單元,每次執(zhí)行完一個(gè)執(zhí)行單元,React Fiber就會(huì)檢查還剩多少時(shí)間,如果沒(méi)有時(shí)間則將控制權(quán)讓出去,然后由瀏覽器執(zhí)行渲染操作,這篇文章主要介紹了React Fiber架構(gòu)原理剖析,需要的朋友可以參考下
    2022-11-11
  • 解決React報(bào)錯(cuò)React.Children.only expected to receive single React element child

    解決React報(bào)錯(cuò)React.Children.only expected to rece

    這篇文章主要為大家介紹了React報(bào)錯(cuò)React.Children.only expected to receive single React element child分析解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-01-01
  • React?Hooks的useState、useRef使用小結(jié)

    React?Hooks的useState、useRef使用小結(jié)

    React Hooks 是 React 16.8 版本引入的新特性,useState和useRef是兩個(gè)常用的Hooks,本文主要介紹了React?Hooks的useState、useRef使用,感興趣的可以了解一下
    2024-01-01
  • Redux中subscribe的作用及說(shuō)明

    Redux中subscribe的作用及說(shuō)明

    由于redux使用這方面有很多的不解,不是很熟練,所以我查找資料,進(jìn)行一個(gè)總結(jié),希望可以鞏固知識(shí),并且能幫助到需要的人,所以我會(huì)寫(xiě)的比較清晰簡(jiǎn)單明了點(diǎn),若有不對(duì)之處,請(qǐng)大家糾正
    2023-10-10
  • React中如何使用scss

    React中如何使用scss

    這篇文章主要介紹了React中如何使用scss問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-03-03

最新評(píng)論