mysql+express+vuexで好きなゲーム一覧を作る

# 好きなゲーム一覧を作る

元々ブログを作ろうと思っていたのですが、まだまだ知識が足りない・・・
静的サイトしか作ったことない、あるいは用意されているAPIを使ってページを作ったことしかないので分からないことだらけ・・・
私がこれから得る知識を得ることでどこまでできるのかな？？付け焼き刃だけどやってみよう！

目次
①どうやってmysqlからexpressはデータを持ってくるの？
②expressとvueはどうやってつなぐの？
③vuexを使ってmysqlからデータを持ってきたい。

## ①どうやってmysqlからexpressでデータを持ってくるの？

サーバーとDBのやりとりをこちらで学びました。

[Progate Web開発パス(Node.js)](https://prog-8.com/courses)

Rubyコースもあったのですが、javascriptが好きなので一旦こちらNode.jsを勉強。
そのかいもあってmysqlとexpressをざっくり理解しました。
mySQL構文をexpressで使っていくイメージでした。

##②expressとvueはどうやってつなぐの？
ここから私のワクワクステージ。
まず最初に参考にさせて頂いたのが下記の記事。
[vueとexpressでSPAを作る](https://qiita.com/y4u0t2a1r0/items/a6aea444efc8e8e65293)

expressとvueを繋げる方法が分かります。
こちらではPOSTを使ってexpressで指定したメッセージをコンソールに表示させています。

ですが私はここで自分の凝り性を発揮してしまいました。

###Vuex使えないだろうか。
色々なVueの本やら記事、動画を見てきましたが、VuexのstoreでAPIと通信することって多いイメージ。①と②の知識があれば自分の好きなデータを好きなように表示できるのでは？？

##③vuexを使ってmysqlからデータを持ってきたい
###バックエンドの設定
まずはmySQLでデータベースを作ってくださいね。
[データベースを作る(プロゲイト)](https://prog-8.com/docs/mysql-database-setup)
私は好きなゲーム一覧ができるようにゲーム名だけのデータベースをとりあえず作りました。

それからサーバー側の設定をしていきます。
まずは`express`を`npm install`して、その他にも下記をインストールします。

* `nodemon` （変更ファイルを検知して自動でサーバーを再起動してくれるようになります。）
* ~~`cors` (サイトのドメインとAPIのドメインが違う場合エラーになってしまうので入れておきます)~~
* `mysql`(expressでmysqlをいじれるようにツールを追加)

```package.json
{
  "name": "backend",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "./node_modules/nodemon/bin/nodemon.js index.js"//変更ファイルを検知して自動でサーバーを再起動してくれるようになります。
  },
  "author": "",
  "license": "ISC",
  "dependencies": {
    "express": "^4.17.1",
    "mysql": "^2.18.1",
    "nodemon": "^2.0.13"
  }
}
```


```backend/index.js
//それぞれ使えるようにrequireします。
const express = require('express')
const mysql = require('mysql');

const app = express()
app.use(express.static('../frontend/dist'))※後述

const connection = mysql.createPool({
  host: 'localhost',
  user: '自分のもので置き換え',
  password: '自分のもので置き換え',
  database: '自分のもので置き換え'
})

app.listen(process.env.PORT || 3000)
```
一応これでexpressとmysqlは繋がっているはず...です。
ちなみにこの状態で`http://localhost:3000/`にアクセスしても何も出てきません。
上記コードのこの部分を見てください。
`app.use(express.static('../frontend/dist'))`
`frontend/dist`を閲覧しているのですがvue側で`npm run build`してないのでまだないですね。

ちゃっちゃかこの部分も作っていきましょう。

###フロントエンドの設定
`vue create frontend`すると`vue-cli`が自動でできちゃいますね。
作る際に出てくる設定でvuexだけ入れとけば今回はとりあえず大丈夫でしょう。
インストールしておくものは`axios`。

`vue-cli`でできる`/frontend/src/component/HelloWorld.vue`は簡単なものに。
とりあえず`template`をお片付けしますかね。`<style>`タグも消しちゃいました。

```/frontend/src/component/HelloWorld.vue
<template>
  <div class="hello">
    <button>get</button>
  </div>
</template>
```
こんな感じで。そしたら`npm run build`。
`http://localhost:3000/`にアクセス。
~~`npm run serve`を叩いて
`http://localhost:8080/`にアクセスしてこんな画面が出てきたら成功です。~~
![スクリーンショット 2021-10-09 13.48.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1955682/ec323754-a53b-c739-0d14-5920b9b7e440.png)

ここまで準備できたら早速画面にゲーム名が出てくるようにコードを書いていきましょう。

下記コードを追加しましょう。

```backend/index.js
app.get('/test', (req, res) => {
  connection.query(
    'SELECT*FROM 自分のテーブル名', (error, results) => {
      res.send(results)
    }
  )
})
```
私はポート番号を指定する記述の上に書きました。
クライアントで`http://localhost:3000/test`にアクセスすると`express`が`mysql`にアクセスしてデータを持ってきてくれるわけですね。
試しに`http://localhost:3000/test`をブラウザで叩くとデータが表示されています。

ここで出てくるVuex。
`frontend/src/store/index.js`を下記のように書いてみましょう。

```frontend/src/store/index.js
import { createStore } from 'vuex'
import axios from 'axios'

axios.defaults.baseURL = 'http://localhost:3000/'

export default createStore({
  state: {
    games: {}
  },
  mutations: {
    gamesSet (state, games) {
      this.state.games = games
    }
  },
  actions: {
    async testGetting (state) {
      const games = await axios.get('/test')
      this.commit('gamesSet', games.data)
    }
  },
  modules: {
  }
})
```
vuexでは`actions`でAPI通信をするようになっているので`actions`メソッドに処理を書きましょう。返ってきたデータを`state`で状態管理するために`mutation`でセットします。
(ここのルールが中々複雑で最初は面倒だなとか思ってしまう。)

いよいよ上記で作った`testGetting()`を画面を操作して呼んでみましょう。

```/frontend/src/component/HelloWorld.vue
<template>
  <div class="hello">
    <button @click="get">get</button>
  </div>
</template>
<script>
export default {
  name: 'HelloWorld',
  data () {
    return {
    }
  },
  methods: {
    get () {
      this.$store.dispatch('testGetting').then(() => {
        this.games = this.$store.state.games
      })
    }
  }
}
</script>
```
上のコードでは`get`と書いてあるボタンをクリックすると`get`関数が呼ばれます。
その中では`this.$store.dispatch('testGetting')`しています。
ご存知のように`store`にある`actions`を呼ぶには決まった呼び方がありますね。`dispatch`。

最後に`/frontend/src/component/HelloWorld.vue`の`template`を修正してリストを画面に表示しましょう！

```/frontend/src/component/HelloWorld.vue
<template>
  <div class="hello">
    <button @click='get'>get</button>
    <ul>
      <li v-for="game in games" :key="game">{{game.name}}</li>
    </ul>
  </div>
</template>
```
`this.$store.dispatch('testGetting')`で取ってきた値を`this.game`に格納することで`<li>`タグの`v-for`が動き、一覧が表示されているはずです。
どうでしょうか、表示されましたか？？

以上となります！

# まとめ
Vue初学者によるアップアップしながら書いた記事なので、間違った部分もあるかもしれません。
でも自分で立てたDBに繋いでデータをやりくりするできて感動でした。
実際に業務でこんな使い方するかは分かんないけども。。。
この知識を生かして今度はデータを追加できるようにしようと思います。
機能を増やしているので、参考になるかは分かりませんがgithubを置いておきます。
https://github.com/AS-box/backend-test

お疲れ様でした！


# 参考にさせて頂いたサイト
[vueとexpressでSPAを作る](https://qiita.com/y4u0t2a1r0/items/a6aea444efc8e8e65293)
[データベースを作る(プロゲイト)](https://prog-8.com/docs/mysql-database-setup)
[express.jsのcors対応](https://qiita.com/chenglin/items/5e563e50d1c32dadf4c3)
[[Node.js][Express]Jsonレスポンスを返す](https://tech.chakapoko.com/nodejs/express/res-json.html)
[Expressでbody-parserがいらない理由: “bodyparser is deprecated”](https://qiita.com/hirochan/items/e63d74cb70f0b97889fc)
[Vuex とは何か？](https://vuex.vuejs.org/ja/)