プログラミング逆引き辞典

~ 多言語対応のプログラミングレシピ ~

Vue.js ToDoリストアプリ作成のサンプルソースコード

■Vue.jsでToDoリストアプリのサンプルソースコード
Vue.jsの基本は下記
Vue.js 基礎編①(基礎・v-if・v-show)
Vue.js 基礎編②(v-for・v-on・methods)
Vue.js 基礎編③(v-bind・computed)
Vue.js 基礎編④(watch・mounted)
 
【index.html】


<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="style.css">
    <title>ToDoリスト</title>
  </head>
  <body>
    <div class="container">
      <div id="result">
        <h1>ToDoリスト</h1>
        <hr>
        <div class="sub_header">
          <div class="list_count">
            ToDoリスト数:{{ listCount.length }} / {{ lists.length }}
          </div>
          <div class="all_del">
            <!-- 一括削除ボタン -->
            <!-- @clickで一括削除ボタン押下時のイベントを設定 -->
            <button type="button" @click="allDel">一括削除</button>
          </div>
        </div>
        <div class="main">
          <!-- @submit.preventで追加ボタン押下時のイベントを設定 -->
          <!-- 「prevent」で他ページへの遷移を防止 -->
          <form @submit.prevent="addList">
            <div>
              <!-- 入力した値を「v-model="newList"」でVue.jsのdataで設定した値と紐づけ -->
              <input type="text" v-model="newList">
              <input type="submit" value="追加">
            </div>
          </form>
          <div>
            <ul>
              <!-- v-for="list in lists"でループ -->
              <!-- 「index」でループの番号を取得 -->
              <li v-for="(list, index) in lists">
                <!-- チェックボックスのチェック有無を「v-model="list.isChecked"」でVue.jsのdataで設定した値と紐づけ -->
                <input type="checkbox" name="checkbox" v-model="list.isChecked">
                <!-- 「:class」は「v-bind:class」と同じ -->
                <!-- 「:class="{checked: list.isChecked}"」でdataの「list.isChecked」がtrueだったら「checked」クラス要素を付与 -->
                <span :class="{checked: list.isChecked}">{{ list.title }}</span>
                <span class="del_mark" @click="delList(index)">[x]</span>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="main.js"></script>
  </body>
</html>

 
【main.js】


(() => {
  'use strict';

  let vm = new Vue({
    el: '#result',
    data: {
    // 「newList」はテキストボックスに入力した値を受ける
      newList: '',
      lists: []
    },
    // ブラウザのLocalStorageにJSON形式で保存
    watch: {
      lists: {
        handler: function(){
          // dataの「lists」は「this.lists」で取得
          localStorage.setItem('lists', JSON.stringify(this.lists));
        },
        deep: true
      }
    },
    // ブラウザのLocalStorageから出力
    mounted: function(){
      this.lists = JSON.parse(localStorage.getItem('lists')) || [];
    },
    // 各イベント時の動作
    methods: {
      addList: function(){
        let item = {
          title: this.newList,
        }
        this.lists.push(item);
        this.newList = '';
      },
      delList: function(index){
        if (confirm('削除しますか?')) {
          this.lists.splice(index, 1);
        }
      },
      allDel: function(){
        if (confirm('一括削除しますか?')) {
          this.lists = this.listCount;
        }
      }
    },
    // 動的に算出
    computed: {
      listCount: function(){
        return this.lists.filter(function(list){
          return !list.isChecked;
        });
      }
    }
  });
})();

 
【style.css】


ul {
  list-style: none;
}

.container {
  font-size: 18px;
  font-family: Verdana,sans-serif;
  width: 500px;
  margin: auto;
}

.sub_header {
  padding: 20px 10px 50px;
}

.list_count {
  float: left;
}

.all_del {
  float: right;
}

.all_select {
  float: right;
  padding-right: 10px;
}

.main {
  clear: both;
}

.del_mark {
  font-size: 14px;
  color: rgb(0,0,200);
  cursor: pointer;
}

.checked {
  color: rgb(200,200,200);
  text-decoration: line-through;
}