目次
18.Nuxt.jsとBulmaでハンバーガーメニュー
状態管理システムvuexが難しすぎて理解できないので、わかりやすいサイトをひたすら写経して理解しようと努力していくシリーズの5回目。
今回は、Nuxt.jsにBulmaを組み込んだら、Vuexストアが理解できた件(20180503更新)を写経してみたいと思います。
→最初、CodeSandbox上で行おうと努力しましたが、どうしても、VuetifyやBulma, Font Awesomeのインストールがうまくいかず、ローカル環境で行う方針に変更しました。そのため、環境構築は、面倒なこととなっています。
初めてのVuex目次
すること
- Nuxt.jsのVuexを用いて、Bulmaのレスポンシブなハンバーガーメニューを実装する
今回は、Nuxt.jsにBulmaを組み込んだら、Vuexストアが理解できた件(20180503更新)を写経させていてだきました。
開発環境
Panasonic CF-RZ4 Window 8.1 Pro VisualStudioCode git version 2.17.1.windows.2 node 10.14.1 yarn 1.12.3
新規Nuxt.jsアプリの作成
- VisualStudioCodeのターミナル画面で、以下を入力
yarn create nuxt-app Nuxt-Bulma-Hamburger3
いろいろ聞かれるので、以下のように設定します。
- プロジェクト名は? ⇒ (Enter)
- プロジェクトの一言説明は? ⇒ (Enter)
- サーバーフレームワークは? ⇒ 使わない
- eslintは使う? ⇒ PWA supportを入れる(Linterは使わない)
- UIフレームワークは? ⇒ bulma
- testフレームワークは? ⇒ 使わない
- レンダリングモードは? ⇒ ユニバーサルじゃなくてシングルページアプリケーション
- axiosモジュールは使う? ⇒ 使わない
- 作者名は? ⇒ (Enter)
- パッケージマネージャは? ⇒ npmじゃなくてyarn
cd Nuxt-Bulma-Hamburger3 yarn run dev
- アドレスをCtrlを押しながらクリックすると、以下のページが開きます。
これで、Nuxt.jsでBulmaを使用する準備が出来ました。
インデックスページ以外のページ(about.vueとcontact.vue)を作成
pages/ディレクトリで、about.vueとcontact.vueの新規作成を行う。
pages/about.vue
<template> <section class="hero is-primary is-bold"> <div class="hero-body"> <h1 class="title is-size-2">About</h1> <h2 class="subtitle is-size-4">NBH3とは?</h2> </div> </section> </template>
pages/contact.vue
<template> <section class="hero is-info is-bold"> <div class="hero-body"> <h1 class="title is-size-2">Contact</h1> <h2 class="subtitle is-size-4">連絡先はこちらです</h2> </div> </section> </template>
ナビゲーションバーのコンポーネントを作成する
components/Navbar.vue
<template> <nav class="navbar is-white" role="navigation" aria-label="main navigation"> <div class="navbar-brand"> <div class="navbar-item">NBH3</div> <div class="navbar-burger" data-target="navMenu"> <span></span> <span></span> <span></span> </div> </div><!-- navbar-brand END --> <div class="navbar-menu" id="navMenu"> <div class="navbar-end"> <nuxt-link to="/" class="navbar-item">トップ</nuxt-link> <nuxt-link to="/about" class="navbar-item">NBHとは?</nuxt-link> <nuxt-link to="/contact" class="navbar-item">お問い合わせ</nuxt-link> </div> </div><!-- navbar-menu END --> </nav> </template>
このNavbar.vueを、layouts/default.vue内に表示するようにします。
ハンバーガーメニューをトグルさせる
横幅を狭くすると、画面右上にハンバーガーメニューが出てきますが、それをクリックしても何も起こりません。
isMenuActiveというプロパティとtoggleMenuというメソッドを定義して、ハンバーガーメニューをクリックすると、縦方向にリンクが表示されるようにします。
<template> ... <div class="navbar-burger" data-target="navMenu" @click="toggleMenu" :class="{'is-active': isMenuActive}"> ... <div class="navbar-menu" id="navMenu" :class="{'is-active': isMenuActive}"> ... </template> <script> export default { data: () => { return {isMenuActive: false} }, methods: { toggleMenu () { this.isMenuActive = !this.isMenuActive } } } </script>
- これで、トグルするようにはなったのですが、リンク先の飛んでも、メニューが開いたままになってしまっています。
- そこで、『ページ遷移』(=リンクがクリックされる)したときに、メニューが閉じる(isMenuActiveプロパティがfalseになる)ようなプログラムを実装します。
- このときに、Vuexを用いると、コンポーネント間の“isMenuActive”の『バケツリレー』を回避することができます。
詳細はhttps://qiita.com/isamusuzuki/items/5ec800e423a3a56ef03d#nuxtjs%E3%82%A2%E3%83%97%E3%83%AA%E3%81%AE%E5%8B%95%E4%BD%9C%E3%82%92%E8%AA%BF%E3%81%B9%E3%82%8Bを読んだのですが、なかなか難しく、結論からいうと、今回と関係があるのは、以下の2つのようでした。
- isMenuActiveの状態管理に、Vuexを使った方がよい
- Nuxt.jsアプリでは、<nuxt-link>経由で特定のページに移動したとき、fetch()メソッドが呼び出される
Vuexストアを設定する
isMenuActiveプロパティの状態(trueかfalseか)を、Vuexストアで管理します(状態管理)。
Nuxt.jsには、デフォルトの状態でVuexが入っており、store/ディレクトリに、index.jsや、xxxx.jsを記載したりすることにより、Vuexのコードを記載します。
『クラシックモード』と、『モジュールモード』があるらしいです。
参考:https://ja.nuxtjs.org/guide/vuex-store/
store/index.js (新規作成)
import Vuex from 'vuex' const store = () => new Vuex.Store({ state: { isMenuActive: false }, mutations: { toggleMenu (state) { state.isMenuActive = !state.isMenuActive }, resetMenu (state) { state.isMenuActive = false } } }) export default store
- layouts/Navbar.vueを編集して、ハンバーガーメニューをクリックすると$storeのtoggleMenu関数を実行し、また、navbar-burgerとnavbar-menuの開閉状態をisMenuActiveプロパティで制御しておくようにします。
... <div class="navbar-burger" data-target="navMenu" @click="$store.commit('toggleMenu')" :class="{'is-active': $store.state.isMenuActive}"> ... <div class="navbar-menu" id="navMenu" :class="{'is-active': $store.state.isMenuActive}"> ...
- VisualStudioCodeのターミナル画面で、一度、Ctrl+C ⇒ Y ⇒ Enterで、サーバを停止したのち、再度、yarn run devを入力し、Nuxtサーバを再起動します。この時点では、まだ、ページ遷移してもトグルは閉じません。
ページ遷移したときにトグルが閉じるようにする
ページ遷移したとき、すなわち、新しいページが描画されてfetch()メソッドを呼び出されたときにトグルが閉じるように(isMenuActiveがfalseになるように)します。
具体的には、各pages/index.vue, about.vue, contact.vueの<script>内に、以下のコードを追加します。
<script> export default { fetch({ store }) { store.commit("resetMenu"); } }; </script>
pages/index.vue
pages/about.vue
pages/contact.vue
今回は以上となります。
ソースコード
今回写経させていただいたサイト
リンク