JavaScript
vue.js
nuxt.js

Nuxt.js と簡易 api サーバで簡単な Guestbook みたいの作ってみる

プロジェクト作成

$ mkdir guestbook
$ cd guestbook
$ emacs package.json
package.json
{
  "name": "guestbook",
  "scripts": {
    "dev": "nuxt"
  }
}

ライブラリをインストール

$ npm install --save nuxt
$ npm install @nuxtjs/axios --save

ちなみに nuxt v1.0.0(2018-01-12現在)

開発用簡易apiサーバに json-serverを利用

$ npm install json-server install -D
$ emacs db.json
db.json
{
  "comments": [
    {
      "id": 1,
      "body": "Hello"
    },
    {
      "id": 2,
      "body": "Hi"
    },
    {
      "id": 3,
      "body": "yey"
    },
    {
      "id": 4,
      "body": "Yummy"
    }
  ]
}

json-server起動して動作確認

$ node_modules/.bin/json-server --watch db.json --port 3333
$ curl http://localhost:3333/comments/
[
  {
    "id": 1,
    "body": "Hello"
  },
  {
    "id": 2,
    "body": "Hi"
  },
  {
    "id": 3,
    "body": "yey"
  },
  {
    "id": 4,
    "body": "Yummy"
  },
  {
    "body": "bowwow",
    "id": 5
  }
]%

Nuxt.js でアプリ作成

pages

$ mkdir pages
$ emacs pages/index.vue
pages/index.vue
<template>
  <section class="container">
    <div>
      <logo/>
      <h1>
        Guestbook
      </h1>
      <div>
          <input @keyup.enter="addComment">
      </div>
      <ul class="comments">
          <li v-for="(comment, index) in comments">
              {{ comment.body }}
          </li>
      </ul>
    </div>
  </section>
</template>

<script>
import axios from 'axios'

const API_URLS = {
  comments_list: 'http://localhost:3333/comments/',
  create_comment: 'http://localhost:3333/comments/'
}

export default {
  async fetch ({ store, params }) {
    let { data } = await axios.get(API_URLS.comments_list)
    store.commit('comments/set', data)
  },
  computed: {
    comments () { return this.$store.state.comments.list }
  },
  methods: {
    async addComment (e) {
      const comment = e.target.value

      if (comment) {
        await axios.post(API_URLS.create_comment, { body: comment })

        e.target.value = ''

        let { data } = await axios.get(API_URLS.comments_list)
        this.$store.commit('comments/set', data)
      }
    }
  }
}
</script>

<style>
.container {
  min-height: 100vh;
  margin-top: 30px;
  display: flex;
  justify-content: center;
  text-align: center;
}
</style>

(styleはスターターテンプレートのものを流用)

store

$ mkdir store
$ emacs store/comments.js
store/comments.js
export const state = () => ({
  list: []
})

export const mutations = {
  set (state, data) {
    state.list = data
  }
}

プロジェクトを起動してブラウザで表示

$ npm run dev

guestbook.gif

ファイル構成

$ tree . -I node_modules
.
├── db.json
├── package-lock.json
├── package.json
├── pages
│   └── index.vue
└── store
    └── comments.js

感想

  • Vue界隈は日本語のドキュメントがあるのがとてもありがたい :pray:
  • api投げる処理は何処に書くのがきれいなんだろう?
  • 一見簡単そうだけどそれなりの規模のアプリ作る場合いろいろ引っかかりそうかも
  • vue と vuex ほぼ初めて書いたから書き慣れてないだけかも
  • vueベースが Nuxt.js で Reactベースが Next.js(名前似過ぎでちょっと分かりづらいw)
  • Vue.js と React.js どちらが好きかで評価が分かれそうかも

参考サイト