一日Nuxt.js入門[ジロッカソン体験記]

# はじめに
ジロッカソン 2018に一人で参加して、現地ではじめマシマシてというチームを組み開発をしました。
チーム決めの時にPWA?Nuxt.js??という自分の謎のワードが飛んでいたのですが、面白そう！と思ってチームを組みました。

プロダクトとしては並んでいる時間に二郎をクリックしてポイントを貯めガチャを引くことができるジロッカーというサービスを作成しました。
<img width=200px src="https://qiita-image-store.s3.amazonaws.com/0/64677/3c0681e0-43ea-2ada-a150-7ecbdc1981f5.gif">


1dayハッカソンだったのですが、その中でNuxt.jsを使ってみた感想をまとめます。
環境構築等は公式に詳しく書かれているため、そちらを参照してください。本投稿では、大枠について紹介します。

# Nuxt.jsとは
Nuxt.jsnの特徴を公式のドキュメントからわかりやすく、2行だけつまんで解説します。詳しくきになる人は、公式([はじめに |Nuxt.js](https://ja.nuxtjs.org/guide))を参照ください
> 1. Nuxt.js とはユニバーサルな Vue.js アプリケーションを構築するためのフレームワークです。
> 2. Nuxt.js は サーバーサイドレンダリング する Vue.js アプリケーションの開発をもっと楽しくするために必要な設定を、あらかじめセットしています。

1. Nuxt.jsではVue.jsのように記述することができます。view側では、もちろんvue同様に、`v-bind`を利用することができ、`data`, `methods`を宣言することができます。
2. Nuxt.jsでは、次の物をサポートしています。

    |機能|サポートしているもの|
    |:---|:---|
    |[Vue 2](https://vuejs.org/)|Vueの記述法(componentsに記述)|
    |[Vue-Router](https://router.vuejs.org/)|routeingパスの設定(pagesに記述)|
    |[Vuex](https://github.com/vuejs/vuex)|SPAを通したデータの保持(storeに記述)|
    |[Vue Server Renderer](https://ssr.vuejs.org/)|レンダリング処理もNuxt.js側で担保しています。保存するとデータが更新され、自動的にViewが再描画されます。|

# Nuxt.jsのファイル構造
Nuxt.jsのファイル構成は以下のようになっています。
それぞれのディレクトリにREADME.mdが記述されており、初心者でも簡単に開発できました。

```
.
├── assets
├── components # (ページの中で利用するcomponentを記述するディレクトリ)
│   └── AppLogo.vue
├── layouts    # (layoutを記述するディレクトリ)
│   └── default.vue
├── middleware
├── nuxt.config.js
├── pages      # (pathを記述するディレクトリ)
│   └── index.vue
├── plugins
├── static
│   ├── favicon.ico
│   └── ticket_vending_machine.jpg
└── store      # (データを保存するディレクトリ)
```


# pages
ルーティングを決めるディレクトリ、ファイル構造を指定すると自動的にpathを生成します。
例えば以下のようなディレクトリ構造を設定すると `/` と `users/:id` を自動的にpathとして割り当てることができます。

```
pages
├── index.vue
└── users
    └── _id.vue
```

# layout
pageが描画される前にlayoutが実行されます。navigationなどは、ここに記述することができます。(ハッカソンではfooterを利用しました。
<img width="756" alt="スクリーンショット 2018-06-10 14.34.44.png" src="https://qiita-image-store.s3.amazonaws.com/0/64677/45f99c85-b743-7111-4d1a-496cdbde3bd1.png">


# assets
画像・CSSなど静的なファイルを置いて置く場所です。`assets/image.jpg`を参照する場合には
画像の参照には`<img src=~assets/image.jpg>`と記述することができます。
vueと同様に、`src`の値を変更する場合は、`v-bind:src`を利用します。

# store
storeでは、`store/index.js`、`store/mutations.js`を作成します。
`store/index.js`では、storeするデータを記述することができます。`store/mutations.js`では、storeで保存する関数を宣言することができます。

```js:store/index.js
import Vuex from 'vuex'

import mutations from './mutations'

const createStore = () => {
  return new Vuex.Store({
    state: {
      counter: 0
    },
    mutations
  })
}

export default createStore
```

```js:store/mutations.js
const mutations = {
  increment(state) {
    state.counter++
  }
}

export default mutations
```

vueで実際に関数を呼び出すためには、`$store.commit('increment')`、`$store.state.counter`として利用することができます。しかし、`import { mapState } from 'vuex'`を利用することにより、vueのなかで関数を宣言することができます。

```html:index/index.vue
<template>
  <div>
    <p>
      <button @click="$store.commit('increment')">{{ $store.state.counter }}</button><br>
      <nuxt-link to="/">Home</nuxt-link>
    </p>
  </div>
</template>
```

# 最後に
一人でハッカソンに参加して、最初は心細い部分が大きかったですが、チームメンバーが支えてくれて、新しい技術を触ることができて、満足することができました。
最後に汚いですがgithubのリポジトリのリンクを貼っておきます。[4geru/jirokkason](https://github.com/4geru/jirokkason)

# 参考文献
- 公式
  - [ルーティング - Nuxt.js](https://nuxtjs.org/guide/routing)
  - [ストア - Nuxt.js](https://ja.nuxtjs.org/examples/vuex-store/)