Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
99
Help us understand the problem. What is going on with this article?
@ayapon

【Nuxt.js】todoアプリを作成してみた①

More than 1 year has passed since last update.

業務でNuxt.jsを使うことになったので、定番ですが簡単なtodoアプリを作成してみました。
本で勉強していると、どの部分から実装していけば分かりにくいところもあるので、
順を追って実装できるように書いてみました。
初めてNuxt.jsを勉強する、とりあえずNuxt.jsで動くものを作ってみたい、という方の参考になると幸いです。

今回作成したアプリ

todoapp_final.png
todo追加/検索/削除機能のみのシンプルなtodoアプリです。

前提

・Node.jsはインストール済(バージョンは現時点でv10.13.0)
・Vue.jsはある程度理解している
(私はVue.js & Nuxt.js超入門で勉強していました)

作成の手順

(1)Nuxt.jsのプロジェクト作成
(2)template作成
(3)store作成
(4)追加機能作成
(5)検索機能作成
(6)削除機能作成
(7)cssファイル作成

この記事では(1)〜(3)、次回の記事で(4)以降について書きます。

(1)Nuxt.jsのプロジェクト作成

公式サイトに書いてある通り、Nuxt.jsはVueアプリケーションを作成するフレームワークです。
todoアプリ作成にあたり、まずはNuxt.jsのプロジェクトを作成します。
プロジェクトを作成したいディレクトリに移動し、以下のコマンドを実行します。
私はDesktopにpracticeというフォルダを作って、そこにsample-todo-appという名前のプロジェクトを作成しました。

$ cd Desktop/practice
$ npx create-nuxt-app sample-todo-app

ProjectNameなど確認する表示が出てきますが、初期設定のままEnterを押していって大丈夫です。
AutherNameは自分の名前のローマ字など適当に入力してください。

installが完了したら、以下のように作成したプロジェクトに移動して実行します。

$ cd sample-todo-app
$ npm run dev

localhost:3000にアクセスして、以下の画面になっていればプロジェクトの作成は完了です。
project_first.png

(2)template作成

作成したプロジェクトのpagesフォルダのindex.vueファイルを開いて、template部分を作成します。

pages/index.vue
<template>
  <section class="container">
    <h1>Todo App</h1>
    <p><input type="text" name="content"/></p>
    <div>
      <button>save</button>
      <button>find</button>
    </div>
    <ul>
      <li>
        <span>hogehoge</span><span>(2019-03-31 15:00)</span><span>×</span>
      </li>
    </ul>
  </section>
</template>

<script>
</script>

(2)sample.png
listの部分は一旦仮でテキストを入力しています。

(3)store作成

続いてstoreを作成していきます。
storeフォルダの中に、index.jsという名前のファイルを作成し、以下のようにコードを書いていきます。

store/index.js
import Vuex from 'vuex';

const createStore = () => {
    return new Vuex.Store({
        state: () => ({
            todos: [
                {content: 'hogehoge', created: '2019-03-31 15:30'}, 
                {content: 'fugafuga', created: '2019-03-31 16:00'}
            ]
        }),
        mutations: {
            insert: function(state, obj) {
                var d = new Date();
                var fmt = d.getFullYear() 
                            + '-' + ('00' + (d.getMonth() + 1)).slice(-2) 
                            + '-' + ('00' + d.getDate()).slice(-2) 
                            + ' ' + ('00' + d.getHours()).slice(-2) 
                            + ':' + ('00' + d.getMinutes()).slice(-2);
                state.todos.unshift({
                    content: obj.content,
                    created: fmt
                })
            },
            remove: function(state, obj) {
                for(let i = 0; i < state.todos.length; i++) {
                    const ob = state.todos[i];
                    if(ob.content == obj.content && ob.created == obj.created) {
                        alert('remove ' + '"' + ob.content + '"');
                        state.todos.splice(i, 1);
                        return;
                    }
                }
            }
        }
    })
}

export default createStore;

Vuexとは?

VuexはVue.jsアプリケーションのための状態管理パターン+ライブラリです。
Nuxt.jsでは表示するページをそれぞれvueファイルとして作成しますが、すべてのページで利用するデータをまとめて保管するための仕組みがVuexです。
コンポーネントからVuexの変数や処理を利用するために$storeという値が用意されていて、その中から値などを取り出すことができます。

stateの中身

todosという配列を設定し、この中にtodoを追加したり削除したりします。
todoには、todoの内容(content)とtodoが追加された日時(created)の2つのプロパティを持たせます。
(一旦仮で2つ、todoを設定しています。)

mutationsの中身

stateの値を変更するための処理をmutationsの中に書きます。

1つめのinsertでは、state(todos)と入力されたtodoを引数として、
入力されたtodoと入力された時間(fmt)を配列todosに追加します。

2つめのremoveでは、insertと同じくstate(todos)と入力されたtodoを引数として、
入力されたtodoの内容と日時が配列todosのtodoと一致した場合に、
「remove (todoの内容)」というalertを表示させ、配列todosから削除します。

todosの表示

ここまでできたらtodosを表示させてみます。
pagesフォルダのindex.vueを以下のように修正します。

pages/index.vue
<template>
  <section class="container">
    <h1>Todo App</h1>
    <p><input type="text" name="content"/></p>
    <div>
      <button>save</button>
      <button>find</button>
    </div>
    <ul>
      <li v-for="(todo, index) in todos" :key="index">
        <span>{{ todo.content }}</span><span>({{ todo.created }})</span><span>×</span>
      </li>
    </ul>
  </section>
</template>

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

export default {
  data: function() {
    return {
      content: ''
    }
  },
  computed: {
    ...mapState(['todos'])
  }
}
</script>

(3)sample.png
mapStateを使うことで、scriptの中ではthis.stateの名前、templateでは{{stateの名前}}でstateの値を利用することができます。
(もしエラーが表示される場合は、再起動してからもう一度localhost:3000にアクセスしてみてください)

おわりに

ここまで、Nuxt.jsでのプロジェクト作成、storeからのデータ利用を中心に説明してきました。
次回、追加/検索/削除機能を実装していきます。

【Nuxt.js】todoアプリを作成してみた②

参考

Vue.js & Nuxt.js超入門

99
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ayapon
フロントエンドエンジニア3年生。
yumemi
みんなが知ってるあのサービス、実はゆめみが作ってます。スマホアプリ/Webサービスの企画・UX/UI設計、開発運用。Swift, Kotlin, PHP, Vue.js, React.js, Node.js, AWS等エンジニア・クリエイターの会社です。Twitterで情報配信中https://twitter.com/yumemiinc

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
99
Help us understand the problem. What is going on with this article?