【Nuxt.js】ハンバーガーボタンとグロナビを実装する

#■目的
**勉強のためNuxt.jsのサンプル集を作る**

##目標1
**ハンバーガーボタンとグローバルナビを実装する**

##ざっくり仕様
* ハンバーガーボタンはクリックしたら「×」になる
* スマホ閲覧時グローバルナビを展開したらするるっとアニメーションする
* グローバルナビのHTMLはPC・スマホ1ソースで行きたい
* わかる範囲内でアトミックデザインを意識する

##default.vue
まずはベースファイルとして以下を用意する。

```vue:layouts/default.vue
<template>
  <div>
    <HtmlHeader />
    <div id="wrap">
      <Nuxt />
    </div>
    <HtmlFooter />
  </div>
</template>

<script>
import HtmlHeader from '@/components/organisms/HtmlHeader.vue'
import HtmlFooter from '@/components/organisms/HtmlFooter.vue'

export default {
  components: {
    HtmlHeader,
    HtmlFooter
  }
}
</script>
```

今回は`components/organisms`の中に`HtmlHeader.vue`というコンポネントを作成し、
そのコンポネントの中でハンバーガーボタンとグロナビのファイルを読み込む。
（と、いうのはどうだろうか、という話で実はまだいろいろ迷ってる）

##HtmlHeader.vue
ここでボタンやリストを読み込んで、クリックした際のイベントとか書く
（で、あってるんだろうか、という話できっともっと良い方法たくさんある）

```vue:components/organisms/HtmlHeader.vue
<template>
  <header id="header">
    <div class="header__inner">
      <h1>Header</h1>
      <BtnHamburger
        :class="{active : gnaviOn}"
        @btnMenu="toggleMenu"
      />
    </div>
    <transition
      @before-enter="beforeEnter"
      @enter="enter"
      @before-leave="beforeLeave"
      @leave="leave"
    >
      <nav
        v-if="gnaviOn"
        class="gnavi"
      >
        <NaviList />
      </nav>
    </transition>
  </header>
</template>

<script>
import BtnHamburger from '@/components/atoms/buttons/hamburger'
import NaviList from '@/components/molecules/lists/navilist'

export default {
  components: {
    BtnHamburger,
    NaviList
  },
  data () {
    return {
      gnaviOn: false
    }
  },

  methods: {
    toggleMenu () {
      this.gnaviOn = !this.gnaviOn
    },
    beforeEnter (el) {
      el.style.height = '0'
    },
    enter (el) {
      el.style.height = el.scrollHeight + 'px'
    },
    beforeLeave (el) {
      el.style.height = el.scrollHeight + 'px'
    },
    leave (el) {
      el.style.height = '0'
    }
  }
}
</script>
※cssは省略
```

##BtnHamburger
これはatomsか？　ということで。クリックしたらemitで渡す。

```vue:components/atoms/buttons/hamburger.vue
<template>
  <div class="btn-hamburger" @click="btnMenu">
    <span />
    <span />
    <span />
  </div>
</template>

<script>
export default {
  methods: {
    btnMenu () {
      this.$emit('btnMenu')
    }
  }
}
</script>
※cssは省略
```

##NaviList
将来的に追記しなければないようなケースが発生するかもしれないけれど、
それはそれでその時考える。初回はシンプルに行きたい。
(これ、もっと分解して配列で処理すべきだよな、と……）

```vue:components/molecules/lists/navilist.vue
<template>
  <ul class="navilist">
    <li>
      <Nuxt-link to="/">
        Home
      </Nuxt-link>
    </li>
    <li>
      <Nuxt-link to="/information/">
        Information
      </Nuxt-link>
    </li>
    <li>
      <Nuxt-link to="/about/">
        About us
      </Nuxt-link>
    </li>
    <li>
      <Nuxt-link to="/contact/">
        Contact
      </Nuxt-link>
    </li>
  </ul>
</template>
※cssは省略
```

##結果
さぁ、これでOK！　と思い確認。
SP版OK。ちゃちゃっと書いたcssもいい感じできれいに見せてくれてる！
と、思ったらPCで確認したときにおかしくなり、一つ忘れていることがありました。

```vue:components/organisms/HtmlHeader.vue
<nav
  v-if="gnaviOn"
  class="gnavi"
>
  <NaviList />
</nav>
```

この`v-if`の書き方だと、PCで`NaviList`が表示されない。
最初に書いたとおり、2ソース書いてcssのメディアクエリで表示/非表示の切り替え、
みたいなことはやりたくないしなぁ、と少し悩みます。

いろいろ難しいなぁ。
と、いうことで調べてしらべて、改善案。

https://qiita.com/MasayukiAbe/items/2e9caf651d7748cf4575