LoginSignup
8
11

More than 5 years have passed since last update.

Vue.jsとVuexとwebpackでTodoListを作ってみた

Last updated at Posted at 2017-09-11

はじめに

前回の「Vue.jsとVuexでTodoListを作ってみた」にwebpackを追加してみたのでその解説を書いていきたいと思います。

成果物

機能は前回と同じく「追加」と、「完了」と、「完了から戻す」3つだけ。

Vue.jsとVuexの簡単な説明は前回のQiitaに書いたので割愛。

次の記事 Vue.jsとVuexとwebpackで単一ファイルコンポーネント化してTodoListを作ってみた

スペック

  • webpackは少しだけ使ったことある
  • nodeとnpmはわりと使ったことある

webpack

公式

いろいろなファイルを1つにまとめるモジュールバンドラ。

今回はVue.jsとVuexと自分の記述したJSを1つのファイルに纏める用途に利用しています。

ソースコード解説

全体

今回は1つのファイルではありませんのでファイルごとに解説していきます。

package.json

npmで作られるパッケージ管理ファイル。

インストールしたのはvue.jsとvuexとwebpack。

webpackを実行するためにscriptを書いています。

{
  "name": "vuex-webpack-todo-sample",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "dev": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "vue": "^2.4.2",
    "vuex": "^2.4.0"
  },
  "devDependencies": {
    "webpack": "^3.5.6"
  }
}

index.html

前回と違うのは直接書いていたJSを移し、vue.jsとvuexを読み込む代わりにbundle.jsを読み込んでいます。

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <title>Vuex Todo Sample</title>
  <link rel="stylesheet" href="">
  <style>
    main {
      display: flex;
    }
    ul {
      list-style: none;
    }
    .wrap {
      padding: 0 10px;
    }
    [v-cloak] {
      display: none;
    }
  </style>
</head>
<body>
  <main id="app">
    <div class="wrap">
      <h2>Todo Input</h2>
      <input type="text" @keyup.enter="addTodoText"/>
    </div>
    <div class="wrap">
      <h2>Todo List</h2>
      <ul v-cloak>
        <li v-for="todo in todos">
          <p>ID : {{todo.id}}</p>
          <p>Text : {{todo.text}}</p>
          <button @click="doneTodo(todo.id)">Done</button>
        </li>
      </ul>
    </div>
    <div class="wrap">
      <h2>Done</h2>
      <ul v-cloak>
        <li v-for="done in dones">
          <p>ID : {{done.id}}</p>
          <p>Text : {{done.text}}</p>
          <button @click="resetTodo(done.id)">Reset</button>
        </li>
      </ul>
    </div>
  </main>
  <script src="js/bundle.js"></script>
</body>
</html>

app.js

前回直接書いていたJSを基本的に移しただけです。
変更点は最初の3行のrequireとuseです。

var Vue = require('vue');
var Vuex = require('vuex');
Vue.use(Vuex);

var store = new Vuex.Store({
  state: {
    todos: [],
    dones: []
  },
  actions: {
    addTodo (context, todo) {
      context.commit('ADD_TODO',todo.text);
    },
    done (context, todo) {
      context.commit('DONE_TODO',todo.id);
    },
    reset (context, todo) {
      context.commit('RESET_TODO',todo.id);
    }
  },
  mutations: {
    ADD_TODO (state, text) {
      var todo = {
        id: 0,
        text: text
      }
      if (state.todos.length !== 0) {
        todo.id = state.todos[state.todos.length -1].id + 1;
      }
      state.todos.push(todo);
    },
    DONE_TODO (state, id) {
      for (var i = 0; i < state.todos.length; i++) {
        if (state.todos[i].id === id) {
          state.dones.push(state.todos[i]);
          state.todos.splice(i, 1);
          break;
        }
      }
    },
    RESET_TODO (state, id) {
      var todo = {};
      for (var i = 0; i < state.dones.length; i++) {
        if (state.dones[i].id === id) {
          todo = state.dones[i];
          state.dones.splice(i, 1);
          break;
        }
      }
      state.todos.push(todo);
      state.todos.sort(function(a,b){
        if(a.id<b.id) return -1;
        if(a.id > b.id) return 1;
        return 0;
      })
    }
  }
});

new Vue({
  el: '#app',
  store: store,
  computed: {
    todos: function() {
      return this.$store.state.todos;
    },
    dones: function() {
      return this.$store.state.dones;
    }
  },
  methods: {
    addTodoText: function(e){
      var text = e.target.value;
      this.$store.dispatch('addTodo', {
        text: text
      });
      e.target.value = '';
    },
    doneTodo: function(id) {
      this.$store.dispatch('done', {
        id: id
      })
    },
    resetTodo: function(id) {
      this.$store.dispatch('reset', {
        id: id
      })
    },
  }
});

webpack.config.js

webpackの設定ファイル。

entryでメインのJSを、outputで出力先を設定。

require('vue');でvue.jsを読み込むためaliasを設定。

vuexも同様に設定。


module.exports = {
  entry: './src/js/app.js',
  output: {
    path: __dirname,
    filename: './src/js/bundle.js'
  },
  resolve: {
    alias: {
      vue: 'vue/dist/vue.js',
      vuex: 'vuex/dist/vuex.js',
    }
  }
};

ビルド

npm run devでbundle.jsを生成する。

所感

ファイルを分割できた。

と言いたいところだけどwebpack使わなくてもファイル分割はできる・・・。

今回webpackいれたのは、Vueのコンポーネントを利用したかったので入れてみました。

次回はVueコンポーネントを作ってみる。

8
11
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
11