#■目的
勉強のためNuxt.jsのサンプル集を作る
##目標1
ハンバーガーボタンとグローバルナビを実装する
##ざっくり仕様
- ハンバーガーボタンはクリックしたら「×」になる
- スマホ閲覧時グローバルナビを展開したらするるっとアニメーションする
- グローバルナビのHTMLはPC・スマホ1ソースで行きたい
- わかる範囲内でアトミックデザインを意識する
##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
ここでボタンやリストを読み込んで、クリックした際のイベントとか書く
(で、あってるんだろうか、という話できっともっと良い方法たくさんある)
<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で渡す。
<template>
<div class="btn-hamburger" @click="btnMenu">
<span />
<span />
<span />
</div>
</template>
<script>
export default {
methods: {
btnMenu () {
this.$emit('btnMenu')
}
}
}
</script>
※cssは省略
##NaviList
将来的に追記しなければないようなケースが発生するかもしれないけれど、
それはそれでその時考える。初回はシンプルに行きたい。
(これ、もっと分解して配列で処理すべきだよな、と……)
<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で確認したときにおかしくなり、一つ忘れていることがありました。
<nav
v-if="gnaviOn"
class="gnavi"
>
<NaviList />
</nav>
このv-if
の書き方だと、PCでNaviList
が表示されない。
最初に書いたとおり、2ソース書いてcssのメディアクエリで表示/非表示の切り替え、
みたいなことはやりたくないしなぁ、と少し悩みます。
いろいろ難しいなぁ。
と、いうことで調べてしらべて、改善案。