🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Vue CLI

Vue CLIは、Vue.jsでアプリケーション開発を行うためのコマンドラインインタフェース(CLI)に基づいた開発ツールです。インタラクティブなプロジェクトの雛形や設定なしで使用できるプロトタイプの作成など、さまざまな機能が用意されています。

Q&A

1回答

648閲覧

vue.jsで理解出来ない動きがあります

K.Y.

総合スコア5

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

Vue CLI

Vue CLIは、Vue.jsでアプリケーション開発を行うためのコマンドラインインタフェース(CLI)に基づいた開発ツールです。インタラクティブなプロジェクトの雛形や設定なしで使用できるプロトタイプの作成など、さまざまな機能が用意されています。

0グッド

1クリップ

投稿2019/10/13 16:30

vue.jsの学習を始めたばかりで、この記事(https://ueqareer.net/2770)を元にtodoアプリを作ってみたのですが(作成したアプリ→https://vue-todo-169c9.firebaseapp.com/)、どうしても理解できない動きがあります。

このアプリではタスク横のチェックボックスを入力すると「完了」ステータスになり、「未完タスク一覧」ボタンで未完了のタスクだけ表示できるのですが、「未完タスク一覧」ボタンを押した上でチェックを入力すると、関係ないタスクまでチェックが入り一覧から消えてしまいます。また、残ったタスクにもなぜか1つチェックが入ってしまいます。

詳しく現象を書くと、
・1番目のタスクにチェックを入れると、消えるのは2番目。チェックが入った状態で残るのは3番目
・「全て」ボタンを押して全タスクを表示すると、3番目のチェックが消える。そして1番目のチェックを外すと2番目のチェックも連動して消える

で、内部の動きを調べてみたところ、
・2番目と3番目に勝手にチェックが入るが、データベース(firebase)上ではタスクのステータス(isComplete)は未完(false)。でもコンソール上でタスクのステータスを確認すると、2番目のステータスは完了(true)になっている
・2番目と3番目のチェックが変わる時、isCompleteのtrue/falseを変換するメソッドupdateIsCompleteTodoは動いていない

というところまで分かりました。が、原因までわかりませんでした。。
動きを調べるほど意味がわからず、正直怪奇現象のように感じています…。

vue.jsに詳しい方、原因をご教授頂けないでしょうか。

ソースコードは以下になります。
(参考にした記事のソースコードそのままです。)

Task.vue

<template> <div class="task"> <h2>タスク</h2> <div> <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><input class="toggle" type="checkbox" v-model="todo.isComplete" v-on:click="updateIsCompleteTodo(todo, key)">{{ todo.name }}</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; this.todosRef = this.database.ref("todos/" + this.uid); // データに変更があると実行されるfunction this.todosRef.on("value", (snapshot) => { this.todos = snapshot.val(); // 再取得してtodosに格納する }); }, computed: { // フィルターの実装showTodoTypeが変更されると実行される filteredTodos: function() { if (this.showTodoType == "all") { return this.todos; } else { var showIsComplete = false; if (this.showTodoType == "complete") { showIsComplete = true; } var filterTodos = {}; for (var key in this.todos) { var todo = this.todos[key]; if (todo.isComplete == showIsComplete) { filterTodos[key] = todo; } } 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; var updates = {}; updates[key] = todo; this.todosRef.update(updates) }, // todoの削除 deleteTodo: function(key) { this.todosRef.child(key).remove(); } } }; </script> <style> </style>

補足情報(FW/ツールのバージョンなど)

macOS Mojave 10.14.5
vagrant 2.0.2
vue-cli 3.11.0
vue 2.6.0
firebase 7.5.0

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

v-modelv-on:click で2回ユーザからのイベントを取得しています(前者は変更イベント、後者はクリックイベント)。

そこで、完了/未完了の状態反映は v-model ではなく v-bind:value を用い、状態変更のイベントを v-on:change ないし v-on:input で取得するように修正するといかがでしょうか。

html

1<input type=“checkbox” v-bind:value=“todo.isComplete” v-on:change=“updateIsCompleteTodo(todo,key)”>

投稿2019/11/05 01:13

kaorun343

総合スコア47

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問