iT邦幫忙

2021 iThome 鐵人賽

DAY 10
0

挑戰目標: MockNative Camp前端


週末也是很多事要做,每天大概都晚上9點到12點是鐵人賽的工作時間,寫code, test, debug和截圖之後才開始寫文章,真的是每天都像在趕末班電車,太慘LA。

今天要做的是
https://ithelp.ithome.com.tw/upload/images/20210925/201403585CcECcuUrr.png
當hover 時會出現下面的東西,這個我會將下面會展開的東西通通寫進去config中,
next.config.js

module.exports = {
    images: {
        domains: ['nativecamp.net'],
        minimumCacheTTL: 60,
    },
    publicRuntimeConfig: {
        navTab: [
            { name: "首頁", image: "https://nativecamp.net/user/images/gnavi/ic_home.svg", imageHov: "https://nativecamp.net/user/images/gnavi/ic_home-h.svg" },
            { name: "指南", image: "https://nativecamp.net/user/images/gnavi/ic_guide.svg", imageHov: "https://nativecamp.net/user/images/gnavi/ic_guide-h.svg" },
            { name: "學習", image: "https://nativecamp.net/user/images/gnavi/ic_study.svg", imageHov: "https://nativecamp.net/user/images/gnavi/ic_study-h.svg" },
            { name: "搜尋・預約講師", image: "https://nativecamp.net/user/images/gnavi/ic_search.svg", imageHov: "https://nativecamp.net/user/images/gnavi/ic_search-h.svg" },
            { name: "其他", image: "https://nativecamp.net/user/images/gnavi/ic_etc.svg", imageHov: "https://nativecamp.net/user/images/gnavi/ic_etc-h.svg" },
        ],
        navDetails: {
            "首頁": [],
            "指南": [
                {
                    "name": "使用方法",
                    "list": ["致初次使用者", "使用方法", "關於上課不限堂數"]
                },
                {
                    "name": "收費・套餐",
                    "list": ["關於費用"]
                },
                {
                    "name": "使用環境",
                    "list": ["支援的瀏覽器", "關於英語會話APP"]
                }
            ], "學習": [
                {
                    "name": "教材",
                    "list": ["瀏覽教材", "課程及教材診斷", "線上商店 (教材購買)"]
                },
                {
                    "name": "精選教材",
                    "list": ["Callan Method(凱倫學習法)", "TOEIC®L&R TEST對策"]
                },
                {
                    "name": "自學內容",
                    "list": ["口說測驗", "口語訓練"]
                }
            ], "搜尋・預約講師": [{
                "name": "講師介紹",
                "list": ["講師一覽", "排名", "評論"]
            },
            {
                "name": "關於講師",
                "list": ["關於母語人士", "關於卡通人物講師"]
            },
            ], "其他": [{
                "name": "推薦內容",
                "list": ["問卷結果 / 會員的心聲"]
            },
            {
                "name": "其他",
                "list": ["上課環境測試", "FAQ (聯絡我們)", "網站導覽"]
            },
            ]
        }
    }
}

然後在header.js中設定選定tab的useState,把set func以props傳進去Nav.jsNavTab.js中,在hover時set tab state為該tab name,因為傳了兩層props很痛苦,之後會用Redux去做優化,我在寫Vue時也遇過要一直傳props的方式加上如果還要commit就會很麻煩,所以我只要可以復用的或是兩個以上component會用到的我一律都用Vuex去處理。

header.js 這邊宣吿了tab的useState,並將setTab以props傳入Nav

import Image from "next/image";
import Nav from "./Nav";
import { useState } from "react"
import NavDetail from "./NavDetail";

function Header() {
    // control nav detail
    const [tab, setTab] = useState("");
    return (
        <header >
            <div className="bg-nativeCamp-header-bg h-header flex justify-center items-center">
                <div className="flex items-center">
                    {/* Left */}
                    <div className=" m-auto py-4 pr-80">
                        <div className="relative flex  h-logo cursor-pointer my-auto">
                            <Image
                                src="https://nativecamp.net/user/images/common/logo_s-zh-tw.png?v=2.1"
                                layout="fill"
                                objectFit="contain"
                                objectPosition="left"
                            />
                        </div>
                        <h1 className="text-white text-headerLogo">
                            線上英語會話的NativeCamp.7天免費體驗進行中!
                        </h1>
                    </div>
                    {/* Right */}
                    <div className=" pl-80 mb-4 space-y-2">
                        <ul className="flex justify-end ">
                            <li>
                                <a
                                    className="text-white text-sm  hover:text-opacity-75"
                                    href="https://nativecamp.net/zh-tw/tutors"
                                >
                                    FOR TUTORS
                                </a>
                            </li>
                        </ul>
                        <ul className="flex space-x-2">
                            <li>
                                <a className='bg-nativeCamp-header-signup hover:bg-nativeCamp-header-signupHov text-white text-center text-xs py-2 px-6 rounded-sm  cursor-pointer'>註冊</a>
                            </li>
                            <li>
                                <a className='bg-nativeCamp-header-login hover:bg-nativeCamp-header-loginHov text-white text-center text-xs py-2 px-6 rounded-sm  cursor-pointer'>登入</a>
                            </li>
                            <li>
                                <a className="bg-transparent hover:border-opacity-75 border border-bg-white text-white text-center text-xs p-2 px-4 rounded-sm  cursor-pointer">重新加入</a>
                            </li>
                        </ul>
                    </div>
                </div>
            </div>
            {/* Nav */}
            <div>
                <Nav setTab={setTab} />
            </div>
            {/* Nav detail */}
            <div>
                <NavDetail tab={tab} />
            </div>
        </header>
    );
}

export default Header;

Nav.js 因為判斷在哪邊hover所以還要將setTab再傳一層,很麻煩

import getConfig from 'next/config'
import NavTab from './NavTab'

function Nav({ setTab }) {

    const { publicRuntimeConfig } = getConfig();
    return (
        <div className="">
            <ul className="flex flex-row items-center justify-center pt-2 border-b">
                {publicRuntimeConfig.navTab?.map(({ image, imageHov, name }) => (
                    <NavTab key={name} image={image} imageHov={imageHov} name={name} setTab={setTab} />
                ))}
            </ul>
        </div>
    )
}

export default Nav

NavTab.ja 這邊在onMouseEnter時去呼叫setTab將tab name放進去

import { useState } from 'react';
import Image from "next/image";

function NavTab({ image, imageHov, name, setTab }) {
    const [isHovering, setIsHovered] = useState(false);
    const onMouseEnter = () => {
        setIsHovered(true)
        setTab(name)
    };
    const onMouseLeave = () => setIsHovered(false);

    return (
        <li className="w-48 flex items-center justify-center cursor-pointer text-nativeCamp-nav-text hover:text-nativeCamp-nav-textHov border-b-4 border-white hover:border-nativeCamp-nav-textHov"
            onMouseEnter={onMouseEnter}
            onMouseLeave={onMouseLeave}>
            <div className="space-y-2 w-48 flex justify-center items-center flex-col">
                <div className="relative flex h-[28px] w-[28px]">

                    {isHovering ? (
                        <Image
                            src={imageHov}
                            layout="fill"
                            objectFit="contain"
                        />
                    ) : (
                        <Image
                            src={image}
                            layout="fill"
                            objectFit="contain"
                        />
                    )}
                </div>
                <div className="pb-2" >
                    <span className="text-sm">{name}</span>
                </div>
            </div>
        </li>
    )
}
export default NavTab

NavDetail.js 這邊我們不先做CSS先看一下是否有成功

import getConfig from 'next/config'

function NavDetail({ tab }) {

    const { publicRuntimeConfig } = getConfig();

    return (
        <div>
            {publicRuntimeConfig.navDetails[tab]?.map(({ name, list }) =>
            (<div>{name}
                <p>{list}</p>
            </div>)
            )}
        </div>
    )
}

export default NavDetail

https://ithelp.ithome.com.tw/upload/images/20210925/20140358DFwInvrLpf.png
很好,成功了,明天在來把CSS給完成。


上一篇
[Day 9]人不作死就不會死(前端篇)
下一篇
[Day 11]在你順利的時候來一拳才是標配(前端篇)
系列文
關於我快30歲的後端工程師,想轉職成全端工程師,在前端世界中尋求機會的那件事(前端篇)18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言