Procházet zdrojové kódy

feat: 手机抽屉菜单

zhaoxinming před 16 hodinami
rodič
revize
21efc9daea

+ 2 - 0
src/App.js → src/App.jsx

@@ -9,6 +9,7 @@ import {ABOUT_US, CONTACT_US, HOME} from "./uitls/Constants";
 import './i18n';
 import React from "react";
 import ScrollToTopButton from "./component/ScrollToTopButton/ScrollToTopButton";
+import Drawer from "./component/Drawer/Drawer";
 
 // 主页面组件
 const App = () => {
@@ -21,6 +22,7 @@ const App = () => {
                     <Route path={CONTACT_US} element={<ContactUs/>}/>
                     <Route path={ABOUT_US} element={<AboutUs/>}/>
                 </Routes>
+                <Drawer/>
                 <Footer/>
                 <ScrollToTopButton/>
             </div>

+ 36 - 25
src/component/Drawer/Drawer.jsx

@@ -1,44 +1,55 @@
 import React, {useEffect, useState} from "react";
 import styles from "./Drawer.module.css";
 import eventBus from "../../uitls/EventBus";
+import {ABOUT_US, CONTACT_US, HOME} from "../../uitls/Constants";
+import {useNavigate} from "react-router-dom";
+import nextBtn from '../../assets/images/product/next.png'
+import {t} from "i18next";
 
 const Drawer = () => {
     const [drawerOpen, setDrawerOpen] = useState(false);
+    const navigate = useNavigate();
 
     useEffect(() => {
-        eventBus.on("drawerState", (state) => {
+        console.log("Drawer Mount");
+        const handleDrawerState = (state) => {
             setDrawerOpen(state);
-        });
+        }
+        eventBus.on("drawerState", handleDrawerState);
         return () => {
-            eventBus.off("drawerState");
+            console.log("Drawer Dismount");
+            eventBus.off("drawerState", handleDrawerState);
         };
     }, []);
 
+    const handleMenuClick = (tab) => {
+        setDrawerOpen(false);
+        eventBus.emit('changeTabEvent', tab)
+        eventBus.emit('drawerStateRecover', true);
+        navigate(tab);
+    }
+
     return (<div className={styles.container}>
-        {/* 手机端菜单按钮 */}
-        {/*<button*/}
-        {/*    className={styles.menuButton}*/}
-        {/*    onClick={() => setDrawerOpen(true)}*/}
-        {/*>*/}
-        {/*    ☰*/}
-        {/*</button>*/}
 
         {/* 左侧抽屉菜单 */}
-        <div
-            className={`${styles.drawer} ${drawerOpen ? styles.open : ""}`}
-        >
-            <button
-                className={styles.closeButton}
-                onClick={() => setDrawerOpen(false)}
-            >
-                ✕
-            </button>
-            <ul className={styles.menuList}>
-                <li>首页</li>
-                <li>关于我们</li>
-                <li>服务</li>
-                <li>联系</li>
-            </ul>
+        <div className={`${styles.drawer} ${drawerOpen ? styles.open : ""}`}>
+            <div className={styles.drawerBg}>
+                <ul className={styles.menuList}>
+                    <li onClick={() => handleMenuClick(HOME)}>
+                        <span className={styles.menuText}>{t('home')}</span>
+                        <img src={nextBtn} className={styles.arrow}/>
+                    </li>
+                    <li onClick={() => handleMenuClick(CONTACT_US)}>
+                        <span className={styles.menuText}>{t('contactUs')}</span>
+                        <img src={nextBtn} className={styles.arrow}/>
+                    </li>
+                    <li onClick={() => handleMenuClick(ABOUT_US)}>
+                        <span className={styles.menuText}>{t('aboutUs')}</span>
+                        <img src={nextBtn} className={styles.arrow}/>
+                    </li>
+                </ul>
+            </div>
+
         </div>
     </div>);
 };

+ 35 - 54
src/component/Drawer/Drawer.module.css

@@ -1,82 +1,63 @@
-/* 容器 */
-.container {
+.drawer {
+    display: none;
 }
 
-/* 桌面端布局:左边菜单,右边内容 */
-@media (min-width: 768px) {
-    .drawer {
-        position: relative;
-        width: 200px;
-        background: #333;
-        color: white;
-        transform: none !important;
-    }
-
-    .menuButton {
-        display: none; /* 桌面端不显示菜单按钮 */
-    }
-
-    .content {
-        flex: 1;
-        padding: 20px;
-    }
-}
+.container{}
 
 /* 移动端布局:抽屉菜单隐藏在左边 */
 @media (max-width: 768px) {
     .drawer {
+        display: flex;
         position: fixed;
-        top: 0;
-        left: 0;
+        top: 17.1vw;
+        left: -1px;
         height: 100%;
-        width: 220px;
+        width: 100%;
         background: #333;
         color: white;
         transform: translateX(-100%);
         transition: transform 0.3s ease-in-out;
         z-index: 1000;
-        padding: 20px;
     }
 
     .drawer.open {
-        transform: translateX(0);
-    }
-
-    .menuButton {
-        position: fixed;
-        top: 10px;
-        left: 10px;
-        background: #333;
-        color: white;
-        border: none;
-        padding: 10px 15px;
-        cursor: pointer;
-        z-index: 1100;
-        border-radius: 4px;
-    }
-
-    .closeButton {
-        background: none;
-        border: none;
-        color: white;
-        font-size: 20px;
-        cursor: pointer;
-        margin-bottom: 20px;
+        transform: translateX(1px);
     }
 
     .menuList {
         list-style: none;
-        padding: 0;
+        width: 100%;
+        padding-top: 12.8vw;
     }
 
     .menuList li {
-        margin: 15px 0;
+        color: #333;
         cursor: pointer;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding-left: 4.0vw;
+        padding-right: 5.33vw;
+        margin-bottom: 7.51vw;
+    }
+    .menuText{
+        color: #333;
+        font-size: 4.31vw;
+        font-weight: bold;
+    }
+
+    .drawerBg {
+        display: flex;
+        justify-content: center;
+        align-items: flex-start;
+        height: 100%;
+        width: 90.1vw;
+        background: white;
     }
 
-    .content {
-        flex: 1;
-        padding: 20px;
-        margin-left: 0; /* 移动端不预留空间 */
+    .arrow {
+        width: 10px;
+        height: 10px;
     }
+
 }

+ 0 - 1
src/component/Footer/Footer.jsx

@@ -24,7 +24,6 @@ const Footer = () => {
     }, []);
 
     const onClick = () => {
-        console.log('点击了:Let\'s Connect');
         eventBus.emit('changeTabEvent', CONTACT_US)
         navigate(CONTACT_US)
     };

+ 15 - 2
src/component/Header/Header.jsx

@@ -1,4 +1,4 @@
-import React from 'react';
+import React, {useEffect, useRef} from 'react';
 import Navigation from "../Navigation/Navigation";
 import logo from '../../assets/images/main/logo.png';
 import Styles from './Header.module.css';
@@ -10,6 +10,8 @@ import eventBus from "../../uitls/EventBus";
 // 顶部导航栏组件
 const Header = () => {
     const {i18n} = useTranslation();
+    const currentMenuState = useRef(true);
+
     const changeLanguage = () => {
         const currentLanguage = i18n.language === 'zh' ? 'en' : 'zh'
         i18n.changeLanguage(currentLanguage);
@@ -20,11 +22,22 @@ const Header = () => {
         const body = encodeURIComponent('');
         window.location.href = `mailto:${email}?subject=${subject}&body=${body}`;
     };
+    useEffect(() => {
+        eventBus.on("drawerStateRecover", (state) => {
+            currentMenuState.current = state;
+        });
+        return () => {
+            eventBus.off("drawerStateRecover");
+        };
+    }, []);
     return (
         <header className={Styles.root}>
             <button
                 className={Styles.menuBtn}
-                // onClick={() => setDrawerOpen(false)}
+                onClick={() => {
+                    eventBus.emit('drawerState', currentMenuState.current);
+                    currentMenuState.current = !currentMenuState.current;
+                }}
             >
             </button>

+ 11 - 6
src/component/Header/Header.module.css

@@ -39,8 +39,8 @@ a {
     .root {
         display: flex;
         justify-content: center;
-        width: 375px;
-        height: 64px;
+        width: 100vw;
+        height: 17.1vw
     }
 
     .navigationState {
@@ -50,14 +50,19 @@ a {
     .menuBtn {
         display: flex;
         position: absolute;
-        font-size: 24px;
-        left: 20px;
+        font-size: 6.4vw;
+        left: 5.33vw;
+        margin-bottom: 2vw;
         border: none;
         background-color: transparent;
+        align-items: center;
+        justify-content: center;
+        text-align: center;
     }
+
     .logoImg {
         object-fit: contain;
-        width: 127px;
-        height: 25px;
+        width: 34.1vw;
+        height: 6.66vw;
     }
 }