挑战目标: MockNative Camp前端
周末也是很多事要做,每天大概都晚上9点到12点是铁人赛的工作时间,写code, test, debug和截图之後才开始写文章,真的是每天都像在赶末班电车,太惨LA。
今天要做的是
当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.js和NavTab.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
很好,成功了,明天在来把CSS给完成。
<<: Day 10 Prototype 制作 - 版面、字体、间距、图示设定小技巧分享
>>: Day10. 人与人之间偶有摩擦,物体与物体之间叫做碰撞 - Collision(上)
BlueScreenView 今天来认识蓝屏 View 这应该是看 Windows 为啥会蓝屏的工具...
既然是电子书阅读器,一般人最常拿来用的功能应该就是看电子书吧。看电子书时如果要翻页的话,通常会点击画...
「你因为两个原因来读这本书:首先,你是位程序设计师。再者,你想成为一位更好的程序设计师」 取自: ...
这边你需要自己制作一个流程控制 不了解的话建可以画个图来确认现在在哪个流程 基本上都会回到主要操控介...
可能会遇到使用 git stash 指令情境: 假想今天可能在公司进行手中任务时,突然接收到老板或是...