React-RouterV6+AntdV4實現(xiàn)Menu菜單路由跳轉(zhuǎn)的方法
React-RouterV6 + AntdV4實現(xiàn)Menu菜單路由跳轉(zhuǎn),采用子路由嵌套的方式
兩種實現(xiàn)方式:
方式一:編程式跳轉(zhuǎn)
使用useNavigate()
方式二:NavLink鏈接式
<Link to="/home">主頁</Link>
配置路由和主頁
App.js
import { Routes, Route, Navigate, useLocation } from 'react-router-dom' import Home from './pages/Home'; import Main from './pages/Main'; import User from './pages/User'; import Auth from './pages/Auth'; function App() { // 獲取瀏覽器url const location = useLocation() const { path } = location console.log(path); return ( <Routes> {/* 重定向到主頁 */} <Route path='*' element={<Navigate to="/home" />} /> {/* 主頁及其子路由 */} <Route exact path='/home' element={<Home />} > {/* url為/home時主動觸發(fā)二級路由 */} <Route exact index element={<Main />} /> <Route exact path='/home/user/list' element={<User />} /> <Route exact path='/home/user/auth' element={<Auth />} /> </Route> </Routes> ); } export default App;
Home/index.js
react-router-dom的Outlet組件,類似于Vue中的router-view,在Outlet處會渲染任何匹配到的子路由組件。
import React from 'react'; import { Breadcrumb, Layout } from 'antd'; import '../../assets/css/layout.css'; import { LaptopOutlined, NotificationOutlined, UserOutlined } from '@ant-design/icons'; import { Outlet } from 'react-router-dom' import SiderLeft from '../../components/SiderLeft.js'; import TopHeader from '../../components/TopHeader'; const { Header, Content, Sider } = Layout; export default class Home extends React.Component { constructor(props) { super(props); this.state = {}; } // 生命周期函數(shù) componentDidMount() { console.log('componentDidMount'); } componentWillUnmount() { console.log('componentWillUnmount'); } render() { return ( <Layout> {/* 頭部 */} <Header> <TopHeader /> </Header> <Layout className="layout-main"> {/* 左側(cè)導航欄 */} <Sider width={200} className="layout-nav-box" style={{ position: 'fixed', left: 0, top: 64, bottom: 0 }} > {/* 渲染左側(cè)菜單組件 */} <SiderLeft /> </Sider> {/* 右邊區(qū)域 */} <Layout style={{ position: 'relative', right: 0, top: 64, marginLeft: 200, padding: '0 24px 24px', }} > <Breadcrumb style={{ margin: '16px 0', }} > <Breadcrumb.Item>Home</Breadcrumb.Item> <Breadcrumb.Item>List</Breadcrumb.Item> <Breadcrumb.Item>App</Breadcrumb.Item> </Breadcrumb> <Content className="layout-content" style={{ padding: 24, margin: 0, minHeight: 280, }} > {/* 渲染子路由 匹配到子路由時,用子路由的組件替換此處內(nèi)容*/} {/* 類似Vue中的router-view */} <Outlet /> </Content> </Layout> </Layout> </Layout> ) } }
一、編程式跳轉(zhuǎn)
編程式跳轉(zhuǎn)的方式使用react-router-dom中的useNavigate方法,傳入url路徑即可進行頁面跳轉(zhuǎn)。
注意:useNavigate不能在類組件中使用,如果你非要在類組件中使用,可以使用高階組件,對類組件進行一個包裹,讓原始類組件擁有useNavigate功能。(函數(shù)組件中使用useNavigate請自行實現(xiàn))
Menu/SiderLeft.js
import { Menu } from 'antd'; import React from 'react'; import { LaptopOutlined, NotificationOutlined, UserOutlined } from '@ant-design/icons'; // 高階組件,包裹useNavigate()功能 import WidthUseNavigate from './withComponents/WithUseNavigate'; class SiderLeft extends React.Component { constructor(props) { super(props); this.state = { items: [{ key: "/home", icon: React.createElement(UserOutlined), label: "概覽" }, { key: "/home/user", icon: React.createElement(UserOutlined), label: "用戶管理", children: [{ key: "/home/user/list", label: "成員管理" }, { key: "/home/user/auth", label: "權(quán)限設(shè)置" }, { key: "sub23", label: "菜單三" }, { key: "sub24", label: "菜單四" }, { key: "sub25", label: "菜單五" }] }] }; } click = (e) => { console.log(e); console.log(e.key); //注意this指向問題,采用箭頭函數(shù)this就指向當前組件 this.props.to(e.key); } openChange() { console.log('OpenChange'); } render() { return ( <Menu theme="light" mode="inline" defaultSelectedKeys={['/home']} defaultOpenKeys={['/home/user']} style={{ height: '100%', borderRight: 0, }} items={this.state.items} onOpenChange={() => this.openChange()} onClick={this.click} /> ) } } // 使用高階組件包裹當前類組件 const NavigateCompont = WidthUseNavigate(SiderLeft); // 導出包裹后的類組件 export default NavigateCompont;
高階組件,包裹useNavigate()功能
widthUseNavigate.js
import { useNavigate } from 'react-router-dom' // 高階組件包裝useNavigate()功能 // 原因:類組件中無法使用useNavigate(),會報錯 // React Hook "useNavigate" cannot be called in a class component. function widthUseNavigate(WrapCompontent) { // 設(shè)置別名 WrapCompontent.displayName = `widthUseNavigate${getDisplayName(WrapCompontent)}` return function NavigateCompont() { const navigate = useNavigate() // 給傳入的組件新增一個to方法,傳給原始組件的props,在原始組件中通過this.props.to(參數(shù))使用 return <WrapCompontent to={navigate}></WrapCompontent> } } // 別名 function getDisplayName(WrapCompontent) { return WrapCompontent.displayname || WrapCompontent.name || 'Component' } export default widthUseNavigate
二、鏈接式跳轉(zhuǎn)
在Menu組件的items中將label的值設(shè)置為<Link to="/home">主頁</Link>,菜單顯示“主頁”,同時具備鏈接跳轉(zhuǎn)功能。
Menu/SiderLeft.js
import { Menu } from 'antd'; import React from 'react'; import { LaptopOutlined, NotificationOutlined, UserOutlined } from '@ant-design/icons'; import { NavLink as Link } from 'react-router-dom'; export default class SiderLeft extends React.Component { constructor(props) { super(props); this.state = { items: [{ key: "/home", icon: React.createElement(UserOutlined), label: <Link to="/home">概覽</Link> }, { key: "/home/user", icon: React.createElement(UserOutlined), label: "用戶管理", children: [{ key: "/home/user/list", label: <Link to="/home/user/list">成員管理</Link> }, { key: "/home/user/auth", label: <Link to="/home/user/auth">權(quán)限設(shè)置</Link> }, { pass... }] }] }; } openChange() { console.log('OpenChange'); } render() { return ( <Menu theme="light" mode="inline" defaultSelectedKeys={['/home']} defaultOpenKeys={['/home/user']} style={{ height: '100%', borderRight: 0, }} items={this.state.items} onOpenChange={() => this.openChange()} /> ) } }
三、實現(xiàn)效果
兩種方式都能實現(xiàn)點擊左側(cè)菜單,右側(cè)內(nèi)容區(qū)顯示不同組件。
Main/index.js
import React from 'react'; export default class Main extends React.Component { constructor(props) { super(props); this.state = {}; } render() { return ( // React.Fragment一般跟在return后面,用來包裹元素,之前一般會用div進行包裹 // Fragment相比于div的好處是在dom中不會增加額外節(jié)點,也可以直接簡寫為<></> <React.Fragment> <div className="layout-content-display"> 主內(nèi)容區(qū) </div> </React.Fragment> ) } }
User/index.js
import React from 'react'; export default class User extends React.Component { constructor(props) { super(props); this.state = {}; } render() { return ( <React.Fragment> <div className="layout-content-display"> 用戶列表 </div> </React.Fragment> ) } }
Auth/index.js
import React from 'react'; export default class Auth extends React.Component { constructor(props) { super(props); this.state = {}; } render() { return ( <React.Fragment> <div className="layout-content-display"> 權(quán)限設(shè)置 </div> </React.Fragment> ) } }
輸入任何未匹配到路由的url,重定向到主頁,默認渲染Main組件
點擊“成員管理”,右側(cè)內(nèi)容展示區(qū)渲染User組件
點擊“權(quán)限管理”,右側(cè)內(nèi)容展示區(qū)渲染Auth組件
到此這篇關(guān)于React-RouterV6+AntdV4實現(xiàn)Menu菜單路由跳轉(zhuǎn)的文章就介紹到這了,更多相關(guān)React-RouterV6菜單路由跳轉(zhuǎn)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- React進行路由跳轉(zhuǎn)的方法匯總
- React路由跳轉(zhuǎn)的實現(xiàn)示例
- React 中常用的幾種路由跳轉(zhuǎn)方式小結(jié)
- react路由跳轉(zhuǎn)傳參刷新頁面后參數(shù)丟失的解決
- react中路由跳轉(zhuǎn)及傳參的實現(xiàn)
- React中的Hooks路由跳轉(zhuǎn)問題
- React中的路由嵌套和手動實現(xiàn)路由跳轉(zhuǎn)的方式詳解
- 基于React路由跳轉(zhuǎn)的幾種方式
- react-router v4如何使用history控制路由跳轉(zhuǎn)詳解
- react 路由跳轉(zhuǎn)的7種方式實現(xiàn)
相關(guān)文章
使用 React Router Dom 實現(xiàn)路由導航的詳細過程
React Router Dom 是 React 應(yīng)用程序中用于處理路由的常用庫,它提供了一系列組件和 API 來管理應(yīng)用程序的路由,這篇文章主要介紹了使用 React Router Dom 實現(xiàn)路由導航,需要的朋友可以參考下2024-03-03React報錯之Object?is?possibly?null的問題及解決方法
這篇文章主要介紹了React報錯之Object?is?possibly?null的問題,造成 "Object is possibly null"的錯誤是因為useRef()鉤子可以傳遞一個初始值作為參數(shù),而我們傳遞null作為初始值,本文給大家分享詳細解決方法,需要的朋友可以參考下2022-07-07react中useEffect函數(shù)的詳細用法(最新推薦)
useEffect是React中的一個Hook,用于在函數(shù)組件中處理副作用(如數(shù)據(jù)獲取、訂閱、手動更改 DOM 等),useEffect屬于組件的生命周期方法,下面通過本文給大家分享react中useEffect函數(shù)的詳細用法,感興趣的朋友跟隨小編一起看看吧2024-06-06React?中使用?Redux?的?4?種寫法小結(jié)
這篇文章主要介紹了在?React?中使用?Redux?的?4?種寫法,Redux 一般來說并不是必須的,只有在項目比較復(fù)雜的時候,比如多個分散在不同地方的組件使用同一個狀態(tài),本文就React使用?Redux的相關(guān)知識給大家介紹的非常詳細,需要的朋友參考下吧2022-06-06