Nuxt.js+Bulmaのレイアウトを爆速で実装する

Nuxt.js+Bulmaの組み合わせがとても使いやすかったので、プロジェクト作成からレイアウト作成までを共有したいと思います。

 

なぜNuxt.js+Bulmaなのか?

Vue.jsベースでフロントエンドを作成するにあたって、bootstrapみたいにjQueryベースのヘビーなCSSフレームワークは使いたくないし、VueのuiコンポーネントのElementUIは、レスポンシブ対応してないし柔軟性がない。そう、求めているのは、コンポーネント・レイアウトがレスポンシブで対応し、CSSベースのシンプルな軽量なCSSフレームワークである。これを満たしているのがBulmaである。未来を感じるモダンなデザインにも惹かれるものがある。

 

【前提条件】

macOS Sierra 10.13

node.js

npm

yarn

 

1からプロジェクトを作りながらNuxt.jsの仕組みを理解したい方はこちらをご覧ください!

Nuxt.js(Vue.js)+ElementUI(UIライブラリ)のフロントエンド環境を1から作る手順
この記事では、Nuxt.js(Vue.js)+ElementUI(UIライブラリ)のフロントエンド環境を1から作る手順を解説していきます。Nuxt.jsプロジェクトを初めて作る方や1からNuxtプロジェクトを作りたい方向けのチュートリアル的...

 

プロジェクト作成

デスクトップにNuxtプロジェクトを作成していきます。

$ cd Desktop
$ yarn create nuxt-app [プロジェクト名]

 

create-nuxt-appコマンドに従って以下のように入力していきましょう。

  1. プロジェクト名は? => [プロジェクト名(任意)]
  2. プロジェクトの一言説明は? => [説明(任意)]
  3. サーバーフレームワークは? => 使わない
  4. UIフレームワークは? => Bulma
  5. レンダリングモードは? => シングルページアプリケーション
  6. axiosモジュールは使う? => 使わない
  7. eslintは使う? => 使わない
  8. 作者名は? => [作成者名]
  9. パッケージマネージャは? => yarn

 

yarnをいれて、プロジェクトを起動

$ cd [プロジェクト名]
$ yarn install
$ npm run dev

 

ブラウザでlocalhost:3000を開くと、Nuxt.jsのデフォルトページが表示されます。

 

font-awesomeをインストール

font-awesomeを使えるようにインストールします。

$ npm install --save @nuxtjs/font-awesome

 

nuxt.config.jsのmodulesに追記する

modules: [
   '@nuxtjs/bulma',
   '@nuxtjs/font-awesome' //追記する
 ]

 

 

レイアウト作成

 

親レイアウトの作成

layouts/default.vue

<template>
 <div class="site">
   <nav-bar/>
   <div class="siteContent">
     <nuxt class="has-text-centered"/>
   </div>
   <footer-bar/>
 </div>
</template>

<script>
   import FooterBar from '~/components/FooterBar.vue'
   import NavBar from '~/components/NavBar.vue'

   export default {
       components: {
           FooterBar,
           NavBar
       }
   }
</script>

 

親レイアウトに読み込むコンポーネントの作成

次に、default.vueに読み込むヘッダーとフッターコンポーネントを作成していきます。

components/NavBar.vue

<template>
   <nav class="navbar has-background-light">
       <div class="navbar-brand">
           <nuxt-link class="navbar-item" to="/">
               <img src="https://bulma.io/images/bulma-logo.png" alt="Bulma" width="112" height="28">
          </nuxt-link>
           <div class="navbar-burger burger" data-target="navbarMenu" @click="showNav = !showNav" :class="{'is-active': showNav}">
               <span></span>
               <span></span>
               <span></span>
           </div>
       </div>
       <div id="navbarExampleTransparentExample" class="navbar-menu" :class="{'is-active':showNav}">
           <div class="navbar-end">
               <nuxt-link class="navbar-item" to="/">
                   Home
               </nuxt-link>
               <div class="navbar-item has-dropdown is-hoverable">
                   <div class="navbar-dropdown is-boxed">
                       <nuxt-link v-for="item in items" :key="item.title" :to="item.url" class="navbar-item">
                           {{ item.title }}
                       </nuxt-link>
                   </div>
               </div>
               <div class="navbar-item">
                   <p class="control">
                       <a class="button is-primary" href="https://github.com/jgthms/bulma/releases/download/0.7.0/bulma-0.7.0.zip">
                               <span class="icon">
                                 <i class="fa fa-download"></i>
                               </span>
                           <span>Download</span>
                       </a>
                   </p>
               </div>
           </div>
       </div>
   </nav>
</template>

<script>
   import feature from '~/pages/feature.vue'
   import contact from '~/pages/contact.vue'

   export default {
       components: {
           feature,
           contact
       },
       data: () => ({
           showNav: false,
           items: [
               { title: 'Home', icon: 'home', url: '/' },
               { title: 'Feature', icon: 'code', url: '/feature' },
               { title: 'Contact', icon: 'question_answer', url: '/contact' }
           ]
       })
   }
</script>

<style>
.navbar {
  margin-bottom: 20px;
}
</style>

 

components/FooterBar.vue

<template>
   <footer class="footer has-background-primary has-text-white">
       <div class="container">
           <div class="content has-text-centered is-info">
               <p>&copy; 2018 HOGE inc.</p>
           </div>
       </div>
   </footer>
</template>

<script>
   export default {
       name: "FooterBar"
   }
</script>

<style scoped>
   footer.footer {
       padding: 0.5em;
   }
</style>

 

 

TOPページ、bulmaテストページを作成

pages/index.vue

<template>
 <section class="container">
   <div>
     <logo/>
     <h1 class="title">Nuxtapp</h1>
     <div class="links">
       <nuxt-link to="/testbulma" class="btn">bulmaテストページへ</nuxt-link>
     </div>
   </div>
 </section>
</template>

<script>
import Logo from '~/components/Logo.vue'

export default {
 components: {
   Logo
 }
}
</script>

 

pages/testbulma.vue

<template>
   <div>
       <section class="section">
           <div class="container">
               <div class="columns is-centered ">
                   <div class="column is-one-third ">
                       <test-card v-for="item in items" :key="item.title" :val="item"></test-card>
                   </div>
                   <div class="column is-one-third">
                       <test-card v-for="item in items2" :key="item.title" :val="item"></test-card>
                   </div>
                   <div class="column is-one-third">
                       <test-card v-for="item in items3" :key="item.title" :val="item"></test-card>
                   </div>
               </div>
           </div>
       </section>
   </div>
</template>

<script>
   import TestCard from '~/components/TestCard.vue'

   export default {
       components: {
           TestCard
       },
       data: () => ({
           items: [
               { title: 'test 1', subtitle: 'Program-01' },
               { title: 'test 2', subtitle: 'Program-02' },
               { title: 'test 3', subtitle: 'Program-03' }
           ],
           items2: [
               { title: 'test 4', subtitle: 'Program-1' }
           ],
           items3: [
               { title: 'test 5', subtitle: 'Program-1' }
          ]
       })
   }
</script>

 

コンポーネントの作成

testbulma.vueに読み込むTestCard.vueを作成していきます。

components/TestCard.vue

<template>
   <div class="card">
       <div class="card-content">
           <h2 class="title">&ldquo;{{ val.title }}&rdquo;</h2>
           <h3 class="subtitle">{{ val.subtitle }}</h3>
       </div>
       <div class="card-footer">
     <span class="card-footer-item">
       <a href="#" class="button is-primary">
         <i class="fa fa-thumbs-o-up"></i>
       </a>
     </span>
           <span class="card-footer-item">
       <a href="#" class="button is-danger">
         <i class="fa fa-thumbs-o-down"></i>
       </a>
     </span>
           <span class="card-footer-item">
       <a href="#" class="button is-info">
         <i class="fa fa-retweet"></i>
       </a>
     </span>
       </div>
   </div>
</template>

<script>
   export default {
       props: ['val']
   }
</script>

<style scoped>
   .card {
       margin-bottom: 8px;
   }
</style>

 

はい、これでNuxt.jsのレイアウトと簡単なページ遷移が完成しました。

 

 

まとめ

Nuxt.jsには、SSRやPWAなど魅力的な要素が多いので、今後も勉強していきたいです。

以下の記事も合わせてご覧ください!

Nuxt.js製のPWAアプリをFirebaseホスティングで公開する
【前提条件】 ・node.js (npm) ・yarn ・vue 以上が導入済み Firebaseでプロジェクト作成 Firebaseは、Googleが提供しているサービスのためGoogleアカウントでロ...