nuxtjsでtodo アプリケーションを作成

# nuxtjsでto doアプリケーションの実装

参考:[nuxt Vuexストア](https://ja.nuxtjs.org/guide/vuex-store/)

## nuxtjsのセットアップ

```terminal
$ vue init nuxt-community/starter-template <project_name>
$ cd <project_name>
$ npm install
$ npm run dev
```

[localhost:3000](localhost:3000)にアクセスして、以下の画像が表示されたら、確認終了。
![nuxt firebase.png](https://qiita-image-store.s3.amazonaws.com/0/144543/78b3a55e-5a2f-7876-e290-46804c751f58.png)


## todo アプリケーションの作成

### ルーティングの追加


project_path/pagesのディレクトリにindex.vueを作成します。

```directory_tree
.
|- pages
|   |- index.vue // root
|   |- todos     // directoryを作成
|       |- index.vue  // fileを作成

```

```pages/todos/index.vue
  <template>
    <div>
      todos
    </div>
  </template>

  <script>
  export default {}
  </script>

  <style>
  </style>

```

以上のようにディレクトリを作成すると動的にルーティングが作成されます。
確認のため、[localhost:3000/todos](localhost:3000/todos)にアクセスしてみると、
自動的にroutingが作成されます。

```directory_tree
.
|- .nuxt
|   |- router.vue //記述が追加されています。
```
参考：[nuxt ルーティング](https://ja.nuxtjs.org/guide/routing/)

### Vuex

#### Vuexの追加

nuxtにはVuexがもともと入っています。
そのため、installする必要はなく、有効化のみで対応可能です。  
参考: [Vuex ストア](https://ja.nuxtjs.org/guide/vuex-store/)

#### Vuexの有効化

```nuxt.config.js
module.exports = {
  /*
  ** Headers of the page
  */
  head: {
    title: 'nuxt-firebase',
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: 'Nuxt.js project' }
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }
    ]
  },
  // ここから
  build: {
    vendor: [
      'vuex',
    ]
  },
  // ここまでを追加
  /*
  ** Customize the progress bar color
  */
  loading: { color: '#3B8070' },
  /*
  ** Build configuration
  */
  build: {
    /*
    ** Run ESLint on save
    */
    extend (config, { isDev, isClient }) {
      if (isDev && isClient) {
        config.module.rules.push({
          enforce: 'pre',
          test: /\.(js|vue)$/,
          loader: 'eslint-loader',
          exclude: /(node_modules)/
        })
      }
    }
  }
}

```

#### Vuex Storeの作成

store/todos.jsファイルを追加して、storeを作成します。


```store/todos.js
export const state = () => ({
  list: []
})

export const mutations = {
  add (state, text) {
    state.list.push({
      text: text,
      done: false,
      id: state.list.length + 1,
    })
  },
  remove (state, { todo }) {
    state.list.splice(state.list.indexOf(todo), 1)
  },
  toggle (state, todo) {
    todo.done = !todo.done
  }
}

```

### View

#### Viewの作成

先ほどroutingで作った、_pages/todos/index.vue_を編集します。
removeがチュートリアルがなかったので、適当に作成。


```todos/index.vue
<template>
  <ul>
    <li v-for="todo in todos" :key="todo.id">
      <input type="checkbox" :checked="todo.done" @change="toggle(todo)">
      <span :class="{ done: todo.done }">{{ todo.text }}</span>
      <button @click="removeTodo(todo)">remove</button>
    </li>
    <li><input placeholder="What needs to be done?" @keyup.enter="addTodo"></li>
  </ul>
</template>

<script>
import { mapMutations } from 'vuex';

export default {
  computed: {
    todos () { return this.$store.state.todos.list }
  },
  methods: {
    removeTodo (todo) {
      this.$store.commit('todos/remove', todo);
    },
    addTodo (e) {
      this.$store.commit('todos/add', e.target.value)
      e.target.value = ''
    },
    ...mapMutations({
      toggle: 'todos/toggle'
    })
  }
}
</script>

<style>
.done {
  text-decoration: line-through;
}
</style>

```

[localhost:3000/todos](http://localhost:3000/todos)にアクセスすると、
CSSがほぼあたっていないものが作成されます。
こんな感じ。

![nuxt firebase (1).png](https://qiita-image-store.s3.amazonaws.com/0/144543/373f9dc2-a50f-6502-6e7e-dc04d7d632e6.png)