nuxt 勉強用 メモ


# nuxt勉強メモ

[Youtube](https://www.youtube.com/playlist?list=PLh6V6_7fbbo8koq2fzoz8lN4gqtPC3Yg4)を参考に勉強して、この動画のメモみたいなものです。

ドットインストールというプログラミング動画学習サービスの方が教えてくださってるのでとってもわかりやすいです。

ぜひチェンネル登録を！！

## nuxtの立ち上げ

```
create-nuxt-app v2.11.1
✨  Generating Nuxt.js project in nuxt-todo-app
? Project name nuxt-todo-app
? Project description My wonderful Nuxt.js project
? Author name yosuke.aramaki
? Choose the package manager Npm
? Choose UI framework None
? Choose custom server framework None (Recommended)
? Choose Nuxt.js modules (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Choose linting tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Choose test framework None
? Choose rendering mode Universal (SSR)
? Choose development tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
```

## ページを作成する

1. practice.vueを作成して`http://localhost:3000/practice`にアクセス

```practice.vue
<template>
  <div>
    <p>勉強</p> 
  </div>  
</template>

```

2. practiceディレクトリを作成して、その中に`index.vue`を作成して`http://localhost:3000/practice`にアクセス

## 全ページにヘッダーを追加する
default.vueにヘッダーを追加する。

```default.vue
<template>
  <div>
    <header>
      <h1>Nuxt-todo-list</h1>
    </header>
    <nuxt />
  </div>
</template>
```

## 画像を表示する

`assets`に`img`ディレクトリを作成しその中に画像データを入れる

```index.vue
<img src="~/assets/img/image1.png">
```

## エラーページを作成する

`layouts`ディレクトリに`error.vue`を作成

```error.vue
<template>
  <div>
    ページが見つかりませんでした。
  </div>
</template>
```

## アンダースコアでパラメーターを受け取る

`about`ディレクトリに`_id.vue`というファイルを作り、`http://localhost:3000/practice/1`にアクセス。`http://localhost:3000/practice/2`としても同じものにアクセスできる

```_id.vue
<template>
  <div>
    <h2>IDをパラメーターで受け取る。</h2>
    <p>{{ $route.params.id }}を受け取りました。</p>
  </div>
</template>
```

####ディレクトリにも渡すことができる
`_category`ディレクトリを作成し、その中に`_page.vue`を作成する
`http://localhost:3000/game/3`にアクセスする。

```_page.vue
<template>
  <div>
    <h2>IDをパラメーターで受け取る。</h2>
    <p>{{ $route.params.category }}の{{ $route.params.page }}ページ目です。</p>
  </div>
</template>


```


## パラメーターのバリデーション
パラメーターを数字のみにしたい場合

```_id.vue
.....

<script>
export default {
  validate({ params }) {
    return /^\d+$/.test(params.id)
  }
}
</script>
```
`^`：最初から
`\d`：数字
`+`：幾つでも
`$/`：最後まで

## ライブラリーをプラグインで利用する

```
npm i element-ui -S
```

`pligins`ディレクトリに`element.js`を作成する

```element.js
import Vue from 'vue'
import Element from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'

Vue.use(Element)
```

nuxt.config.jsにプラグインを書き込む

```nuxt.config.js
  plugins: [
    '~/plugins/element.js'
  ],
```

```practice/index.vue
<template>
  <div>
    <img src="~/assets/img/Libra-Freemarket-icon.png">
    <h3>Vueの練習</h3>

    <div style="padding: 30px;"> 
      <el-button @click="visible = true">ボタン</el-button>
      <el-dialog :visible.sync="visible" title="確認">
        <p>処理されました</p>
      </el-dialog>  
    </div>  
  </div>  
</template>

<script>
export default {
  data: function() {
    return {
      visible: false
    }
  }
}
</script>
```

## デバックツール

Chrome extensionのVue.js Devtoolを利用する。

## Vuexのストア

[Nuxt.js 公式](https://nuxtjs.org/guide/vuex-store)に載ってる。

`store`に`todos.js`というファイルを作る

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

export const mutations = {
  add (state, text) {
    state.list.push({
      text: text,
      doen: false
    })
  },
  toggle (state, todo) {
    todo.done = !todo.done
  }
}
```

`pages`ディレクトリに`todo.vue`を作成する。

```todo.vue
<template>
  <div style="margin: 20px;">
    <ul>
      <li v-for="todo in todos">
        <input type="checkbox" :checked="todo.done" @change="toggle(todo)">
        <span :class="{ done: todo.done }">{{ todo.text }}</span>
      </li>
    </ul>    
    <input placeholder="タスクを追加" @keyup.enter="addTodo">
  </div>  
</template>

<script>

import { mapMutations } from 'vuex'
export default {
  computed: {
    todos () {
      return this.$store.state.todos.list
    }
  },
  methods: {
    addTodo(e) {
      this.$store.commit('todos/add', e.target.value)
    },
    ...mapMutations({
      toggle: 'tools/toggle'
    })
  }
  
}
</script>

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

## 学習項目

v-vindとは


# Vue.jsもついでに

## 基本形

基本JSと同じ

```idnex.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Vue.jsのサンプル</title>
</head>
<body>
  <div id="app">
    {{ message }}
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

  <script>
    var app = new Vue({
      el: "#app",
      data: {
        message: "ともすた"
      }
    })
  </script>
</body>
</html>
```

`element`で`app`を指定しているので、`div`のapp属性にJSを反映させる。

## 分岐・ループ

`v-if`：ディレクティブ

```index.html
...

  <div id="app">
    <p v-if ="error">エラーです</p>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script>
    var app = new Vue({
      el: "#app",
      data: {
        error: true
      }
    })
  </script>

...

```

## 属性の書き換え

`v-bind:`　色々な属性をVueで割り当てる

```index.html
  <div id="app">
    <p v-bind:class="error_class">エラーです</p>
    <img v-bind:src="src-img">
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

  <script>
    var app = new Vue({
      el: "#app",
      data: {
        error_class: "error",
        img_src: 'img01.png',
      }
    })
  </script>
```

## ボタンをクリックした際の処理

`v-on:click` クリックした際にイベントが発生する。 
関数を利用する際には`methods: {}`を使う。
`this.now = ` で `now`を上書きする。

```index.html
  <div id="app">
    <p>{{ now }}</p>
    <button v-on:click="time">時刻を表示</button>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

  <script>
    var app = new Vue({
      el: "#app",
      data: {
        now: "00:00:00",
      },
      methods: {
        time: function(e) {
          var date = new Date();
          this.now = date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds(); 
        }
      }
    })
  </script>
```

## 配列の表示

`v-for="変数名in 配列名`
`data`の中で配列を作る。

```index.html
  <div id="app">
    <ul>
      <li v-for="pref in prefs">
        {{ pref.name }}
      </li>
    </ul>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>

  <script>
    var app = new Vue({
      el: "#app",
      data: {
        prefs: [
          { name: '北海道' },
          { name: '青森' },
          { name: '岩手' },
          { name: '山形' },
          { name: '宮城' },
        ]
      }
    })
  </script>
```

## Vue.jsのアニメーション

シャッフルは[Lodash](https://lodash.com)を利用する

`transition-group`を使うことで特別なCSSを使うことができる。
子要素は`key`が必要。``v-bind:key`は`:key`と省略できる。

styleで`.flip-list-move`とすると`flip-list`が動いた時とすることができる。

```html
<style>
  .flip-list-move {
    transition: transform .5s;
  }
</style>

<body>
  <div id="app">
    <button v-on:click="shuffle">シャッフル</button>
    <transition-group name="flip-list" tag="ul">
      <li v-for="pref in prefs" v-bind:key="pref.name">
        {{ pref.name }}
      </li>
    </transition-group>
    </ul>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>

  <script>
    var app = new Vue({
      el: "#app",
      data: {
        prefs: [
          { name: '北海道' },
          { name: '青森' },
          { name: '岩手' },
          { name: '山形' },
          { name: '宮城' },
        ]
      },
      methods: {
        shuffle: function() {
          this.prefs = _.shuffle(this.prefs);
        }
      }
    })
  </script>
```

## 再生可能なコンポーネント

`Vue.component`でコンポーネントを作成できる。
`<template>`を使うときは``で囲む必要がある。


```html
<div id="app">
    <alert-box></alert-box>
  </div>

  <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.15/lodash.min.js"></script>

  <script>
    Vue.component('alert-box' , {
      template: `
       <div class="alert" v-on:click="caution">
        <strong>error!</strong>
        <slot></slot>
      </div>`,
      methods: {
        caution: function() {
          alert('クリックされました');
        }
      }
    })
    var app = new Vue({
      el: "#app",
    })
  </script>
```

#　感想

ほとんどの言語に言えるけど、Nuxt.js慣れたら使いやすそうwww