Vue.js・Nuxt.js でハンバーガーメニューを作成する方法

VueHamMenu

こんにちはフロントエンドエンジニアのまさにょんです!

今回は、Vue.js・Nuxt.jsでハンバーガーメニューを作成する方法について解説していきます。

Vue.js・Nuxt.js でハンバーガーメニューを作成する方法

実務で、Vue.js・Nuxt.js でハンバーガーメニューを作成する機会があったので、

Vue.js・Nuxt.js でハンバーガーメニューを作成する方法をまとめていきます。

ハンバーガーメニューの要件定義

今回作成するハンバーガーメニューの要件定義は、次のとおり。

  1. Mobile版の Headerにのみ表示する。
  2. ハンバーガーメニューを Clickすると、Menuの画面を表示する。

次のような ハンバーガーメニューを作成します。

ハンバーガーメニューを Clickすると、Menuの画面を表示する。

Vue.js・Nuxt.js でハンバーガーメニューを作成する SampleCode

Vue.js・Nuxt.js でハンバーガーメニューを作成する SampleCodeは、次のようになります。

<!-- Mobile専用_Header_HambergerMenu -->
<template>
  <div>
    <!-- Logo_Imgae -->
    <header class="mobile_header_wrapper">
      <div class="mobile_header_logo_wrapper">Robotama Project🔥</div>
      <div class="mobile_header_btn_block_wrapper">
        <!-- User Icon : MyPageに移動する -->
        <button class="user_icon" @click="goToMyPage">
          <img
            src="~/assets/image/mobile/header/user_icon.svg"
            alt="User Icon"
          />
        </button>
        <!-- ハンバーガーメニュー・Open_Btn -->
        <button class="hamburger" @click="clickMenu">
          <!-- ハンバーガーメニューのボタン -->
          <div class="hamburger_btn">
            <span class="line line_01" :class="{ btn_line01: activeMenu }">
            </span>
            <span class="line line_02" :class="{ btn_line02: activeMenu }">
            </span>
            <span class="line line_03" :class="{ btn_line03: activeMenu }">
            </span>
          </div>
        </button>
        <!-- サイドバー -->
        <transition name="menu">
          <div class="menu" v-show="activeMenu">
            <ul>
              <li>
                <!-- ✖️ Icon : 閉じる_Btn -->
                <div>
                  <button class="close_btn" @click="clickMenu">
                    <img
                      src="~/assets/image/mobile/header/icon_cross_wh.svg"
                      alt="Menu"
                    />
                  </button>
                </div>
              </li>
              <li @click="clickMenu">
                <nuxt-link to="/">
                  <div class="nav_tab_container">
                    <span class="title">HOME</span>
                    <span class="sub_title">ホーム</span>
                  </div>
                </nuxt-link>
              </li>
              <li @click="clickMenu">
                <nuxt-link to="/robotama">
                  <div class="nav_tab_container">
                    <span class="title">ROBOTAMA</span>
                    <span class="sub_title">ロボ玉</span>
                  </div>
                </nuxt-link>
              </li>
              <li @click="clickMenu">
                <nuxt-link to="/maritama">
                  <div class="nav_tab_container">
                    <span class="title">MARITAMA</span>
                    <span class="sub_title">まり玉</span>
                  </div>
                </nuxt-link>
              </li>
              <li @click="clickMenu">
                <nuxt-link to="/hakutou">
                  <div class="nav_tab_container">
                    <span class="title">HAKUTOU</span>
                    <span class="sub_title">白桃さん</span>
                  </div>
                </nuxt-link>
              </li>
              <li @click="clickMenu">
                <nuxt-link to="/momo">
                  <div class="nav_tab_container">
                    <span class="title">MOMO</span>
                    <span class="sub_title">ももちゃん</span>
                  </div>
                </nuxt-link>
              </li>
            </ul>
          </div>
        </transition>
      </div>
    </header>
    <!-- Fixed によって、隠れる問題の対応 -->
    <div class="header_fixed_height_div"></div>
  </div>
</template>
<script>
export default {
  name: "MobileHeader",
  components: {},
  data() {
    return {
      activeMenu: false,
    };
  },
  methods: {
    goToMyPage() {
      this.$router.push("/my-page");
    },
    clickMenu() {
      // 真偽値を反転する => Open / Close
      this.activeMenu = !this.activeMenu;
    },
  },
};
</script>
<style lang="scss" scoped>
/* -------------- COMMON -------------- */

/* Btn_Default_Style を無効化する */
@mixin disable_default_button_style {
  background-color: transparent;
  border: none;
  cursor: pointer;
  outline: none;
  padding: 0;
  appearance: none;
}

/* -------------- SECTIONS -------------- */

/* Header_全体を包み込む_Wrapper */
.mobile_header_wrapper {
  display: flex;
  flex-direction: row;
  justify-content: center;
  align-items: center;
  align-content: center;
  height: 64px;
  padding-top: 16px;
  vertical-align: middle;
  width: 100%;
  background-color: white;
  // 上部に固定する
  // z-index: $z-index-high;
  z-index: 998;
  position: fixed;
  top: 0;
  left: 0;
}

.mobile_header_logo_wrapper {
  cursor: pointer;
}

/* User_Icon & Menu Block_Wrapper */
.mobile_header_btn_block_wrapper {
  position: absolute;
  right: 20px;
  margin-bottom: 12px;

  /* User Icon */
  .user_icon {
    // Btn_Default_Style を無効化する
    @include disable_default_button_style;
    margin-right: 12px;
    margin-left: -15px;
  }

  /* Hamberger Icon */
  .hamberger {
    @include disable_default_button_style;
  }
}

/* ハンバーガーボタン */
.hamburger_btn {
  width: 18px;
  height: 37px;
  cursor: pointer;

  .line {
    position: absolute;
    top: 0;
    left: 20px;
    width: 25px;
    height: 2px;
    background: #333333;
    text-align: center;
  }

  .line_01 {
    top: 16px;
    transition: 0.4s ease;
  }
  .line_02 {
    top: 26px;
    transition: 0.4s ease;
  }
  .line_03 {
    top: 36px;
    transition: 0.4s ease;
  }

  /* ハンバーガー・Menu の 3つの Line */
  .btn_line01 {
    transform: translateY(10px) rotate(-45deg);
    transition: 0.4s ease;
    color: #fff;
  }
  .btn_line02 {
    transition: 0.4s ease;
    opacity: 0;
    color: #fff;
  }
  .btn_line03 {
    transform: translateY(-10px) rotate(45deg);
    transition: 0.4s ease;
    color: #fff;
  }
}

/* メニュー画面 */
.menu {
  /* background-color: rgba(197, 197, 197, 0.671); */
  background: #000000;
  /* 画面全体を覆います */
  // z-index: $z-index-highest;
  z-index: 999;
  width: 100%;
  height: 100%;
  padding: 2rem 1rem;
  position: fixed;
  top: 0;
  right: 0;

  /* 閉じるBtn */
  .close_btn {
    @include disable_default_button_style; // Btn_Default_Style を無効化する

    position: absolute;
    right: 20px;
  }

  li {
    list-style: none;
    line-height: 1;
  }
  ul {
    margin: 1rem;
    padding: 0;
  }
  // a {
  //   color: #fff;
  //   text-decoration: none;
  //   font-size: 1.2rem;
  //   padding: 0 2rem;
  // }

  /* Nav_Tab: 1つの項目の Container */
  .nav_tab_container {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 5px;
    color: #fff;

    .title {
      font-size: 22px;
      font-weight: lighter;
      color: #fff;
    }

    .sub_title {
      font-size: 12px;
      color: #fff;
      margin-bottom: 20px;
    }
  }
}

/* Fixed によって、隠れる問題の対応 */
.header_fixed_height_div {
  height: 80px;
}
</style>

SVG素材

SVG素材の表示は、こちらの SVGViewer で確認することができます。

× マーク・Icon ( 白色 )

× マーク・Icon ( 白色 )で、ハンバーガーメニューを開いた後に表示する Close_Btnとして使用しています。

<svg width="35" height="35" viewBox="0 0 35 35" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24.6094 10.3906L10.3906 24.6094M10.3906 10.3906L24.6094 24.6094" stroke="white" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

× マーク・Icon ( 黒色 )

<svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M20.0469 1.02344L0.953125 19.0315M0.953125 1.02344L20.0469 19.0315" stroke="#666666" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

User Icon

User Icon の SVG素材です。

<svg width="25" height="24" viewBox="0 0 25 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M22.8887 19.6874C21.5498 17.4315 19.4591 15.6737 16.9531 14.6971C18.1993 13.7998 19.1198 12.5489 19.5843 11.1215C20.0487 9.69412 20.0336 8.16262 19.541 6.74395C19.0484 5.32527 18.1033 4.09135 16.8396 3.21697C15.5759 2.34259 14.0577 1.87207 12.5 1.87207C10.9423 1.87207 9.42403 2.34259 8.16034 3.21697C6.89665 4.09135 5.95158 5.32527 5.45898 6.74395C4.96639 8.16262 4.95125 9.69412 5.41571 11.1215C5.88017 12.5489 6.80069 13.7998 8.04686 14.6971C5.54093 15.6737 3.45023 17.4315 2.11132 19.6874C2.02835 19.8154 1.97306 19.9582 1.94872 20.1072C1.92438 20.2562 1.9315 20.4084 1.96964 20.5547C2.00778 20.701 2.07618 20.8384 2.17076 20.9588C2.26534 21.0792 2.38417 21.1802 2.5202 21.2556C2.65622 21.3311 2.80666 21.3795 2.96257 21.398C3.11847 21.4165 3.27667 21.4047 3.42774 21.3634C3.57882 21.322 3.71969 21.252 3.84199 21.1573C3.96428 21.0626 4.06551 20.9453 4.13964 20.8124C5.90917 17.8761 9.03417 16.1249 12.5 16.1249C15.9658 16.1249 19.0908 17.8771 20.8603 20.8124C21.021 21.0604 21.2758 21.2387 21.5709 21.3096C21.866 21.3805 22.1783 21.3385 22.4417 21.1924C22.7051 21.0463 22.899 20.8076 22.9824 20.5267C23.0658 20.2458 23.0322 19.9449 22.8887 19.6874ZM7.42186 8.99988C7.42186 8.0357 7.71969 7.09317 8.27768 6.29148C8.83567 5.48979 9.62877 4.86495 10.5567 4.49597C11.4846 4.12699 12.5056 4.03045 13.4907 4.21855C14.4757 4.40666 15.3806 4.87096 16.0908 5.55274C16.801 6.23452 17.2846 7.10316 17.4805 8.04882C17.6765 8.99447 17.5759 9.97467 17.1916 10.8655C16.8072 11.7563 16.1563 12.5176 15.3212 13.0533C14.4862 13.589 13.5043 13.8749 12.5 13.8749C11.1537 13.8734 9.86292 13.3593 8.91093 12.4454C7.95893 11.5315 7.42342 10.2924 7.42186 8.99988Z" fill="#666666"/>
</svg>

ハンバーガー・メニューの Icon

今回は、CSSで、ハンバーガー・メニューの Iconを作成している( 開閉のアニメーションもある )ので、

使用していませんが、SVGアイコンで、ハンバーガー・メニューを表現する方法もあります。

<svg width="21" height="22" viewBox="0 0 21 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<g clip-path="url(#clip0_109_2215)">
<path d="M0 1.90479H21M0 10H21M0 18.0953H21" stroke="#666666" stroke-width="2.5"/>
</g>
<defs>
<clipPath id="clip0_109_2215">
<rect width="21" height="22" fill="white"/>
</clipPath>
</defs>
</svg>

JavaScript書籍 Ver. 中級-上級者向け

JavaScript書籍 Ver. 初級者向け

参考・引用

  1. Vue.jsで頑張るハンバーガーメニュー

Twitterやってます!Follow Me!

神聖グンマー帝国の逆襲🔥

神聖グンマー帝国の科学は、世界一ぃぃぃぃぃぃ!!!!!

最近の投稿