質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.93%

Vue.jsとFirebaseを用いたToDoアプリで完了、未完了、とフィルターをかけた状態でタスク管理をしたい。

受付中

回答 0

投稿

  • 評価
  • クリップ 0
  • VIEW 151

ura148

score 0

初めて質問させていただきました。よろしくお願いいたします。

前提・実現したいこと

todoリストのアプリ作成を行っています。
その際未完タスク一覧や完了タスク一覧を表示した状態でタスクの完了未完了を管理するチェックボックスを押すと他のタスクまでチェックボックス が外れてしまいます。

発生している問題・エラーメッセージ

フィルターで【全て】を選んでいる状態で各ToDoのチェックボックスを操作しても問題ないのですが、
【未完タスク一覧】【完了タスク一覧】を選択した状態でToDoのチェックボックスを操作すると1個下と2個下のToDoのチェックボックスまで操作してしまいます

該当のソースコード

<template>
  <div class="task">
     <h2>タスク</h2>
    <div>
      <!-- 初期はVーmodelで"newTodoName"を入れているが空白、故にタスク作った後に空白にしないとミスが起こる -->
      <input type="text" v-model="newTodoName">
      <button type="submit" v-on:click="createTodo()">タスク作成</button>
    </div>
    <ul>
      <li><button type="submit" v-on:click="showTodoType = 'all'">すべて</button></li>
      <li><button type="submit" v-on:click="showTodoType = 'active'">未完タスク一覧</button></li>
      <li><button type="submit" v-on:click="showTodoType = 'complete'">完了タスク一覧</button></li>
    </ul>
    <!-- todoの一覧表示 -->
    <ul v-for="(todo, key) in filteredTodos" :key="todo.id">
      <li class="card"><input type="checkbox" v-model="todo.isComplete" v-on:click="updateIsCompleteTodo(todo, key)">{{ todo.name + key }}</li>
      <button type="submit" v-on:click="deleteTodo(key)">削除</button>
    </ul>
  </div>
</template>
<script>
import firebase from "firebase";

export default {
  name: "Task",
  data() {
    return {
      database: null,
      todosRef: null,
      newTodoName: "",
      showTodoType: "all",
      todos: []
    };
  },
  created: function() {
    this.database = firebase.database();
    this.uid = firebase.auth().currentUser.uid;
    // refはreferenceでデータベースにある特定の項目を指し示すメソッド
    this.todosRef = this.database.ref("todos/" + this.uid);
    // データに変更があると実行されるfunction
    var _this = this;
    this.todosRef.on('value', function(snapshot) {
      _this.todos = snapshot.val(); // データに変化が起きたときに再取得する
    });
  },
  computed: {
    // フィルターの実装showTodoTypeが変更されると実行される
    filteredTodos: function () {
      if (this.showTodoType == 'all') {
        return this.todos;
      } else {
        var showComplete = false;
        if (this.showTodoType == 'complete') {
          showComplete = true
        }
        var filterTodos = {};

        for (var key in this.todos) {
          var todo = this.todos[key];
          if (todo.isComplete == showComplete) {
            filterTodos[key] = todo;
            console.log(filterTodos[key]);
          }
        }
        console.log(filterTodos);
        return filterTodos;
      }
    }
  },
  methods: {
    // DBのtodos/[uid]/以下にデータを格納していく
    createTodo: function() {
      if (this.newTodoName == "") { return; }
      this.todosRef.push({
        name: this.newTodoName,
        isComplete: false,
      })
      this.newTodoName = "";
    },
    // 完了・未完了の値の更新
    updateIsCompleteTodo: function(todo, key) {
      todo.isComplete = !todo.isComplete;
      // DB内のデータを更新する
      var updates = {};
      // todo.idで変更するtodoタスクを指定し、dataが更新されたtodoを挿入する
      updates[key] = todo;
      this.todosRef.update(updates)
    },
    // todoの削除
    deleteTodo: function(key) {
      this.todosRef.child(key).remove();
    }
  }
};
</script>

試したこと

デバッグをし続けた結果、

this.showTodoType == 'all'


ではない時の下記のループ処理内においてなぜか操作したToDoのチェックボックスの1個下と2個下のToDoのチェックボックスまで操作している事はわかりました。しかしここではチェックボックスの真偽値に関わる

 isComplete: false,


の操作はありません。なぜ影響してしまっているのかわかりません。

else {
        var showComplete = false;
        if (this.showTodoType == 'complete') {
          showComplete = true
        }
        var filterTodos = {};

        for (var key in this.todos) {
          var todo = this.todos[key];
          if (todo.isComplete == showComplete) {
            filterTodos[key] = todo;
            console.log(filterTodos[key]);
          }
        }
        console.log(filterTodos);
        return filterTodos;
      }
    }
  },


解決方法が分かる方がいらっしゃいましたら教えていただけると幸いです。
よろしくお願いいたします。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

まだ回答がついていません

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.93%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • トップ
  • Vue.jsに関する質問
  • Vue.jsとFirebaseを用いたToDoアプリで完了、未完了、とフィルターをかけた状態でタスク管理をしたい。