DAY 18 制作 Nav Bar - dropdown

针对 dropdown 的部分,我们要来细节微调他的 style ,让他符合 vogue 上的设计,并且将 header 拉出来作为 component,让 App.js 更乾净整洁。

抽出 header 区域

首先新增一个资料夹在 src 底下,并命名为 components,在里面新增 Header.js 这里要注意 React 的命名规则为『开头大写驼峰式』,不然 eslint 会来找你麻烦:D

-src
|--components
|	|-- Header.js

并且把原本在 App.js 中 Header 的部分搬移到 Header.js 底下

// Header.js

import React from "react";

export default function Header() {
  
  return (
    <nav className="header">
      <div className="top">
        <label className="logo">VOGUE</label>
        <label className="menu">
          <div className="menu-item">
            <div className="dropdown">
              <label>
                <span>Taiwan</span>
              </label>
              <div className="dropdown-content">
                <ul>
                  <li>
                    <a href="/">arabia</a>
                  </li>
                </ul>
              </div>
            </div>
          </div>
          <div className="menu-item">
            <a href="/">membership</a>
          </div>
          <div className="menu-item">
            <a href="/">
             ---
            </a>
          </div>
        </label>
      </div>
      <div className="sub-menu">
        <a href="/">FASHION</a>
        <a href="/">BEAUTY</a>
        <a href="/">ENTERTAINMENT</a>
        <a href="/">LIFESTYLE</a>
        <a href="/">LUXURY</a>
        <a href="/">VIDEO</a>
        <a href="/">VOGUE有意识</a>
      </div>
    </nav>
  );
}

之後在 App.js 中引入

// App.js

import "../src/assets/sass/main.sass";
import Header from "./components/Header";
function App() {
  return (
    <div className="container">
      <Header />
    </div>
  );
}

export default App;

接下来开始处理 dropdown 的样式

dropdown

首先在 header 中先分别定义 dropdown 的 class

<div className="dropdown">
  <label className="dropdown-label">
    <span>Taiwan</span>
  </label>
  <div className="dropdown-content">
    <ul>
      <li>
        <a href="/">arabia</a>
      </li>
    </ul>
  </div>
</div>

在 sass 中定义符合 VOGUE 样式的 dropdown

.dropdown
    position: relative
    display: inline-block

    &-content
        display: none
        position: absolute
        right: 10px
        min-width: 120px
        background-color: $primary-background-color
        box-shadow: 0px 8px 16px 0px $gray
        padding: 12px 16px
        z-index: 1

    &-label:hover
        color: $secondary-color
        cursor: pointer

    ul
        padding: 8px
        li
            list-style-type: none
            padding: 16px
            &:hover
                display: block
                color: $secondary-color

    .show
        display: block

使用 & 的方法带入 nesting 上层的名称,像是这里带入的是 dropdown,那下面的 class 就会去抓"dropdown-content"这个 class 的内容。

在 content 的部分可以看到 display: none,因为是要点击之後才会打开 content,这里我还设定了一个 show 的 class,就是用作等等显示用的。

回到 Header.js ,我们先简单写一个小 func 来让 label 可以做点击并打开我们 dropdown-content

const [activeDropdown, setActiveIndex] = React.useState(false); 
// 使用 hooks 储存并设定开启关闭的状态,预设 false 为关闭

const handleOnClick = () => {
  setActiveIndex(!activeDropdown); // 点击时开关变换状态
};

//设定国家
const location = [
  "arabia",
  "australia",
  "brasil",
  "britain",
  "china",
  "czechoslovakia",
];

然後在下方 html 的部分

<div className="dropdown">
  <label
    onClick={() => handleOnClick()} 
    className="dropdown-label"
  >
    <span>Taiwan</span>
  </label>
  <div
    className={
      activeDropdown === true
        ? "dropdown-content show"
        : "dropdown-content"
    }
  >
    <ul>
      {location.map(function (country) {
        return (
          <li>
            <a href="/">{country}</a>
          </li>
        );
      })}
    </ul>
  </div>
</div>
  1. 在 label 中使用 onclick func 来呼叫我们上面写好的方法,来开关整个 dropdown-content
  2. 如果 activeDropdown 状态是 true 就将 show 这个 class 加上 dropdown-content,若为 false 则不增加,来隐藏内容。这边要注意的是 show 要放在後面,display 的属性才不会被盖掉
  3. location 的部分用一个简单的 map 把 array 中的内容 render 出来,让我们不用一直写重复的部分。

大概就是以上这样啦!我们明天见!


除此之外,也欢迎大家走走逛逛关於我们团队夥伴的文章

lu23770127 - SASS 基础初学三十天

10u1 - 糟了!是世界奇观!

juck30808 - Python - 数位行销分析与 Youtube API 教学

HLD - 浅谈物件导向与Design Pattern介绍

SiQing47 - 前端?後端?你早晚都要全端的,何不从现在开始?


<<:  DAY21: NPM模块管理工具

>>:  IT铁人DAY 18-Adapter 适配器模式

DAY25 - [React hook] props

今日文章目绿 前言 实作需求 过程纪录 参考资料 昨天讲到component零组件组装的方法,但没...

【Day17】电子商务与行销篇-部落格

#odoo #开源系统 #数位赋能 #E化自主 部落格是网站功能的一种型态,与一般网页较不同的地方是...

30天学会 Python: Day 10-读进来!写出去!

绝对路径&相对路径 电脑中所有的档案和目录(资料夹)形成一个树状的结构 一个目录下可以有多个...

[Day 7] 餐前浓汤 pt.4-资料内文取得及储存

上一篇我们提到了如何观察并且取出我们要的资料 也成功地把资料取出来了 这一篇我们将要对资料做最後的加...

企划实现(10)

FB登入 第一步:到FB官网并创建帐号 https://developers.facebook.co...