[初心者向け]ゼロから始めるNuxt.js入門




# Nuxt.jsについて
Nuxt.jsは、ディレクトリ構成やルーティングやレンダリングなどを行ってくれるVue.jsのフレームワークです。名前の似ているReactのフレームワークであるNext.jsから着想を得たそうです。
下に公式のドキュメントを貼っておきます。
https://ja.nuxtjs.org/

ドキュメントからNuxt.jsの特徴を以下に簡単に書き出すと、

- vue.jsで記述する
- サーバーサイドレンダリングできる（初回のリクエストをサーバーサイドでレンダリングして返すので初期表示が早い。）
- ルーティング等もよしなにやってくれる(pagesディレクトリにファイル追加すると自動ルーティング)

といった特徴があります。

また、nuxt.jsではある程度インストール時点でWebpackやBabelなどの環境が整っているため、環境設定に時間を使わなくて済むといった利点もあります。


# vue.jsについて
vue.jsはJavascriptのフレームワークです。
下に公式のドキュメントを貼っておきますね。
https://jp.vuejs.org/v2/guide/

nuxt.jsで用いるvue.jsについて以下に特徴を説明していきます。

- **コンポーネントでできている**  
              
Vue.jsは、ReactやAngularともよく比較され、どれもコンポーネント構築のためのフレームワークです。Vue.jsでできることはReactと非常によく似ています。
基本的なコンポーネントの作り方の例としては、

```javascript.
Vue.component('area-list__title', {
  template: '<h1>エリア一覧</h1>'
})
```
でarea-list__titleというcomponetを登録し、.vueファイルのtemplate中で

```vue.
  <area-list__title></area-list__title>
```
の形で呼ぶことができます。これはレンダリングされると、

```html.
<h1>エリア一覧</h1>
```

と表示されます。


また、子コンポーネントには親コンポーネントと子コンポーネントを作ることができます。
両者の間はデータを受け渡すことができ、これは**双方向データバインディング**と言います。（vue.jsの特徴）
親→子へデータを渡す際にはpropsを、子→親の時はemitを使ってコンポーネント間のデータをやりとりします。

公式のwikiにコンポーネント間のデータの受け渡しについて詳しく説明されています。
https://jp.vuejs.org/v2/guide/components.html

このコンポーネントの考えにより非同期処理を行うことができます。


- **controllerがない**

vue.jsではMVCの派生種である、GUIライブラリに適したMVVMを設計基盤として採用し、構築されています。
MVVMとはモデル(M)とビュー(V)間のやり取りをビューモデル(VM)を介して行う設計のことで、双方向バインディングによってモデルとビューを接続しています。

- **ディレクティブ**
 
ビューの要素に付加できる独自属性です。ビューの要素に独自属性を付加することでビューモデルのデータとビューの表示、ビューモデルのメソッドとビューの要素のイベントを紐付けます。
例としてv-on、v-modelなどがあります。以下に例を書くと、

```html
<div id="sample">
　<div class="name-list" v-for="list in nameLists">
　  <p>名前：{{list.name}}</p>
　</div>
</div>
```
ここでのlistは自分で設定できます。nameListsは以下のようにデータで引き渡されます。

```javascript.

new Vue ({
  el: "#sample",
  data: {
      nameLists: [
          {"name": "山田"},
          {"name": "田中"},
          {"name": "佐藤"},
      ],
  }
})

```
とすると、出力は

```text.

名前: 山田
名前: 田中
名前: 佐藤
```

となり、反復処理を行ってくれます。


- **UIライフサイクルを管理してくれる**

Vueインスタンスの生成から消滅までの一連の過程のことです。createdとmountedのように特定のタイミングで処理を割り込ませることができます。これも詳しくは公式ドキュメントに解説されています。

- **パーツからページまで作ることができる**
 
vue.jsはhtmlからCDNで読み込んで部分的に使うこともできますが、ページ全体も作ることができます。サイトをvue.jsで作るには、ルーティングやレンダリングなどをよしなに行ってくれるフレームワークを使うのが楽です。

フレームワークとしてはVueCLI3とNuxt.jsがよく使われています。

次のセクションではNuxt.jsを用いて簡単なアプリケーションを作成していきます。


# Nuxt.jsを用いためちゃくちゃ簡易的なTODOアプリの作成

まず、ライブラリとしてnpmとnodeをインストールしておきましょう。手順を順番に説明していきます。


- **アプリ作成**
 
Desktop上のターミナルにおいて

```bash.

npx create-nuxt-app アプリ名
```
として、Nuxt.jsのプログラムを作成しましょう。
作成時に質問をされますが、ひとまず初期設定でEnterを押して作成しました。




- **起動**

次にアプリを

```bash.
npm run dev
```
で起動させます。

- **pages/index.vueをいじる**
 
今回はTODOアプリを作成するのでボタンを作成します。pages/index.vueのtemplateに

```html.
      <div id="app">
        <h1 class="title">
          アプリ名
        </h1>
        <input type="text">
        <form>
          <button v-on:click="addItem">add</button>
        </form>
        <h2 class="subtitle">
          アプリ名
        </h2>
      </div>
```
次にvue.jsのデレクションを用いてクリック時の処理について書いていきます。`v-on:click="addItem"`でクリック時のアクションを定義できます。
さらにディレクションを設定します。

```html.
      <div id="app">
        <h1 class="title">
          アプリ名
        </h1>
        <input type="text" v-model="newItem">
        <form v-on:submit.prevent>
          <button v-on:click="addItem">add</button>
        </form>
        <li v-for="todo in todos">
          {{ todo.item }}
        </li>
        <h2 class="subtitle">
          アプリ名
        </h2>
      </div>
```
のように設定し、入力した値が表示されるようにしていきます。このままではデータが入っていないので、データがバインディングするように設定します。index.vueに

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

export default {
  components: {
    Logo
  },
  data() {
    return {
      newItem: '',
      todos: []
    }
  },
  methods: {
    addItem: function(event) {
      var todo = {
        item: this.newItem
      };
    this.todos.push(todo)
    }
  }
}
</script>
```
とするとボタンを押して入力した時にTODOリストが表示されるようになります。



![スクリーンショット 2019-04-09 21.25.29.png](https://qiita-image-store.s3.amazonaws.com/0/340121/d86a46c4-0c5e-5e1a-01ac-5f0cee3d2388.png)


TODOアプリはNuxt.jsのアプリを作る際によく例にされるので他にも記事をみてぜひカスタマイズしてみてください。


TODOアプリの参考になるサイト
https://qiita.com/Gma_Gama/items/0cef921fb83fbf83ef2e
https://qiita.com/Gma_Gama/items/0cef921fb83fbf83ef2e



# 他に参考になる記事
Nuxt.jsのpluginの導入
https://qiita.com/yfujii1127/items/cddf267a94fa30ecb0b8


componentの使い方
https://app.codegrid.net/entry/2017-light-vue-1

双方向データバインディング
https://qiita.com/Sa2Knight/items/544b3f157108b96033fe

至らない部分についてはぜひフィードバックをいただけると嬉しいです。