Help us understand the problem. What is going on with this article?

BulmaのハンバーガーメニューをVue.jsで実装する

More than 1 year has passed since last update.

はじめに

こんにちは、普段はサーバーサイドを担当しているsekiと申します。
今、個人開発で掲示板を作っており、UIフレームワークにBulmaを採用しました。が
初っ端、公式リファレンスからコピペしたヘッダーのハンバーガーメニューが動きませんでした。:tired_face:
調べても日本語の記事で解決方法が出てこなかったので、解決方法を簡単にまとめたいと思います。 すでに似た記事がqiitaに投稿されていました:bow:
どうやらJavaScriptを導入しないと動かないみたいです。
今回はVue.jsを使って動かしてみたいと思います:wink:

1.Starter templateにナビゲーションバーを表示させてみる

公式リファレンスのクイックスタート用のテンプレートナビゲーションバーを表示させてみたいと思います。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Hello Bulma!</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css">
    <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
  </head>
  <body>
  <nav class="navbar" role="navigation" aria-label="main navigation">
    <div class="navbar-brand">
      <a class="navbar-item" href="https://bulma.io">
        <img src="https://bulma.io/images/bulma-logo.png" width="112" height="28">
      </a>

      <a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample">
        <span aria-hidden="true"></span>
        <span aria-hidden="true"></span>
        <span aria-hidden="true"></span>
      </a>
    </div>

    <div id="navbarBasicExample" class="navbar-menu">
      <div class="navbar-start">
        <a class="navbar-item">
          Home
        </a>

        <a class="navbar-item">
          Documentation
        </a>

        <div class="navbar-item has-dropdown is-hoverable">
          <a class="navbar-link">
            More
          </a>

          <div class="navbar-dropdown">
            <a class="navbar-item">
              About
            </a>
            <a class="navbar-item">
              Jobs
            </a>
            <a class="navbar-item">
              Contact
            </a>
            <hr class="navbar-divider">
            <a class="navbar-item">
              Report an issue
            </a>
          </div>
        </div>
      </div>

      <div class="navbar-end">
        <div class="navbar-item">
          <div class="buttons">
            <a class="button is-primary">
              <strong>Sign up</strong>
            </a>
            <a class="button is-light">
              Log in
            </a>
          </div>
        </div>
      </div>
    </div>
  </nav>
  </body>
</html>

ブラウザで確認するとしっかりヘッダーが表示されています!!
スクリーンショット 2019-02-12 21.10.01.png

しかし、レスポンシブ時のハンバーガーメニューをクリックしてもうんともすんとも言いません・・・・困りました。

それでは早速Vue.jsを使用してハンバーガーメニューを動かしてみましょう!

Vue.jsでハンバーガーメニューを動かす

まずはCDNでVue.jsを読み込みます。

index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Hello Bulma!</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css">
    <script defer src="https://use.fontawesome.com/releases/v5.3.1/js/all.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>   <!-- 追加する行 -->
  </head>
  <body>
                           ~省略~

これでVueを使えるようになりました。

続いて、nav要素をdivで囲みます。

index.html
<body>
  <div id="app">      <!-- 追加する行 -->
      <nav class="navbar" role="navigation" aria-label="main navigation">
        <div class="navbar-brand">
        <a class="navbar-item" href="https://bulma.io">
            <img src="https://bulma.io/images/bulma-logo.png" width="112" height="28">
        </a>

                            ~省略~
    </nav>
  </div>            <!-- 追加する行 -->

次にVueインスタンスを作成します。

index.html
<script>
var app = new Vue({
    el: '#app',
    data: {
        isOpen: false
    }
})
</script>

ここで定義したisOpenはハンバーガーメニューを表示するために使用します。
次はクリックイベントを設定して実際にハンバーガーメニューを開いてみましょう。

index.html
<nav class="navbar" role="navigation" aria-label="main navigation">
  <div class="navbar-brand">
    <a class="navbar-item" href="https://bulma.io">
      <img src="https://bulma.io/images/bulma-logo.png" width="112" height="28">
    </a>

    <a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample" @click="isOpen = !isOpen" v-bind:class="{'is-active': isOpen}">  <!-- 変更する行 -->
      <span aria-hidden="true"></span>
      <span aria-hidden="true"></span>
      <span aria-hidden="true"></span>
    </a>
  </div>

  <div id="navbarBasicExample" class="navbar-menu" v-bind:class="{'is-active': isOpen}">     <!-- 変更する行 -->
  <div class="navbar-start">

                            ~省略~                    

これでハンバーガーメニューが動くようになりました!

スクリーンショット 2019-02-13 21.54.12.png

最後に変更した二箇所の解説をさせていただきます。

変更箇所の一行目

<a role="button" class="navbar-burger burger" aria-label="menu" aria-expanded="false" data-target="navbarBasicExample" @click="isOpen = !isOpen" v-bind:class="{'is-active': isOpen}">

この行には@click="isOpen = !isOpen"v-bind:class="{'is-active': isOpen}">が追加されています。
@click="isOpen = !isOpen"でなにが起きてるか解説します。

@clickはクリックを検知してisOpen = !isOpenを実行します。
つまり、ハンバーガーメニューをクリックした時(@click)にisOpenに格納されている真理値が反転する処理(isOpen = !isOpen)が行われます。

v-bind:class="{'is-active': isOpen}">ではisOpenがtrueの時にclassにis-activeが追加される処理が行われています。

変更箇所の二行目

<div id="navbarBasicExample" class="navbar-menu" v-bind:class="{'is-active': isOpen}">
ここでは先ほどと同じようにv-bind:class="{'is-active': isOpen}"が追加されています。
ハンバーガーメニューがクリックされた時にこの要素のclassにis-activeが追加されます。

まとめ

色々と書きましたが、やっていることはただ要素のclassにis-activeを追加したり消したりしているだけです。
BulmaはどのJavaScriptの環境にも適応できるので、柔軟性があってとても便利ですね:v:

seki19
PHP/Golang/jsに興味あります。
https://note.com/seki19
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away