ラジオボタンの表示ごとにタスクの表示を切り替えをしたい Vue.js
前提・実現したいこと
Vue.jsでToDoリストを作成しています。
ラジオをボタンの選択を切り替えた際に表示も変更するようにしたいです。
<ここに質問の内容を詳しく書いてください。>
Vue.jsでTodoリストを作成しているのですが、
ラジオボタンを変更したあと、うまく作動しなくなってしまいます。
ラジオボタンを切り替えても、どのタスクを選択しても、完了、作業中が切り替わり。
完了のラジオボタンを選択している場合は、完了と表示されているタスクのみ表示され、
作業中のラジオボタンを選択している際は、作業中と表示されているタスクのみ表示したいです。
また、完了中に新しいタスクを入力しても表示されずに、タスクとしては、追加されているようにしたいです。
発生している問題・エラーメッセージ
ラジオボタンを変更したあと、うまく作動しなくなってしまいます。
「すべて」のラジオを選択しているときは、作業中と完了のボタンは、うまく作動している。
しかし、作業中や完了のラジオを選択しているとインデックスの逆から押さなければ、
全ての項目を正しく切り替えることができない。
例)
○すべて ●作業中 ○完了
1.A 作業中
2.B 作業中
3.C 作業中
→A→B→Cと押すとAが完了に切り替わったあと、Bを完了に変えようとすると再び、作業中のAが表示されてしまう。
しかし、CからB、Aと押すと問題なく変更される。
エラーメッセージ
該当のソースコード
HTML
1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8"> 6 <title>ToDo List Vue-version</title> 7 8 <link rel="stylesheet" href="css/styles.css"> 9</head> 10 11<body> 12 <h2>ToDoリスト</h2> 13 <div id="app"> 14 <label><input type="radio" name="list" value="all" v-model="filter">すべて</label> 15 <label><input type="radio" name="list" value="active" v-model="filter">作業中</label> 16 <label><input type="radio" name="list" value="completed" v-model="filter">完了</label> 17 <p>ID コメント 状態</p> 18 <table> 19 <tr v-for="(todo, index) in filteredTodos"> 20 <td>{{ index }}</td> 21 <td>{{ todo.title }}</td> 22 <td><button @click="statusChange(index)"> 23 <span>{{ todo.statusBtn }}</span> 24 </button></td> 25 <td><button @click="deleteTask(index)">{{ todo.delBtn }}</button></td> 26 </tr> 27 </table> 28 <h2>新規タスクの追加</h2> 29 <form @submit.prevent="addTask"> 30 <input type="text" v-model="newTask"> 31 <input type="submit" value="追加" class="button"> 32 </form> 33 </div> 34 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 35 <script> 36 'use strict'; 37 38 new Vue({ 39 el: '#app', 40 data: { 41 statusBtn: '', newTask: '', todos: [], filter: 'all' 42 }, 43 computed: { 44 filteredTodos() { 45 if (this.filter === 'all') { 46 return this.todos 47 } else if (this.filter === 'completed') { 48 return this.todos.filter((todo) => { 49 return todo.statusBtn === '完了' 50 }) 51 } else if (this.filter === 'active') { 52 return this.todos.filter((todo) => { 53 return todo.statusBtn === '作業中' 54 }) 55 } 56 } 57 }, 58 methods: { 59 addTask: function () { 60 let item = { 61 title: this.newTask, statusBtn: '作業中', delBtn: '削除' 62 } 63 this.todos.push(item); 64 this.newTask = ''; 65 }, 66 statusChange: function (data) { 67 if (this.todos[data].statusBtn === '作業中') { 68 this.todos[data].statusBtn = '完了' 69 } else { 70 this.todos[data].statusBtn = '作業中' 71 } 72 }, 73 deleteTask: function (index) { 74 this.todos.splice(index, 1); 75 } 76 } 77 }); 78 </script> 79</body> 80 81</html>
試したこと
ここに問題に対して試したことを記載してください。
https://cr-vue.mio3io.com/tutorials/todo.html#step2-%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E3%82%B9%E3%83%88%E3%83%AC%E3%83%BC%E3%82%B8-api-%E3%81%AE%E4%BD%BF%E7%94%A8
上記のサイトのコードを参考にして、ラジオボタンを含め、フィルター部分から修正しようとしたのですが、
下記のようなエラーが出てしまいました。そして、dataの中にstate:0を追加したのですが、改善されませんでした。
**********
[Vue warn]: Property or method "item" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
[Vue warn]: Error in render: "TypeError: Cannot read property 'state' of undefined"
(found in <Root>)
・・・・
**********
HTMLVue
1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8"> 6 <title>ToDo List Vue-version</title> 7 8 <link rel="stylesheet" href="css/styles.css"> 9</head> 10 11<body> 12 <h2>ToDoリスト</h2> 13 <div id="app"> 14 <label v-for="label in options"><input type="radio" v-bind:value="label.value" v-model="current" 15 name="label">{{ label.label }}</label> 16 <p>ID コメント 状態</p> 17 <table> 18 <tr v-for="(todo, index) in filteredTodos" v-bind:key="index"> 19 <td>{{ index }}</td> 20 <td>{{ todo.title }}</td> 21 <td><button @click="statusChange(item)">{{ labels[item.state] }}</button></td> 22 <td><button @click="deleteTask(index)">削除</button></td> 23 </tr> 24 </table> 25 <h2>新規タスクの追加</h2> 26 <form @submit.prevent="addTask"> 27 <input type="text" v-model="newTask"> 28 <input type="submit" value="追加" class="button"> 29 </form> 30 </div> 31 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 32 <script> 33 'use strict'; 34 35 new Vue({ 36 el: '#app', 37 data: { 38 options: [ 39 { value: -1, label: 'すべて' }, 40 { value: 0, label: '作業中' }, 41 { value: 1, label: '完了' } 42 ], 43 newTask: '', 44 todos: [], 45 current: -1, 46 }, 47 computed: { 48 filteredTodos() { 49 return this.todos.filter(function (todo) { 50 return this.current < 0 ? true : this.current === todo.state 51 }, this) 52 }, 53 labels() { 54 return this.options.reduce(function (a, b) { 55 return Object.assign(a, { [b.value]: b.label }) 56 }, {}) 57 } 58 }, 59 methods: { 60 addTask: function () { 61 let item = { 62 title: this.newTask, 63 state: 0 64 } 65 this.todos.push(item); 66 this.newTask = ''; 67 }, 68 statusChange: function (item) { 69 item.state = item.state ? 0 : 1 70 }, 71 deleteTask: function (index) { 72 this.todos.splice(index, 1); 73 } 74 } 75 }); 76 </script> 77</body> 78 79</html>
補足情報(FW/ツールのバージョンなど)
ここにより詳細な情報を記載してください。
残りタスクが1つになった後、削除ボタンが作動しなってしまいました。
削除ボタンを押すとすべてのタスクを削除できるようにし、連番も再び初めからふりなおすにしたいのですが、
これは、新たに質問をした方が良いでしょうか?
HTMLVue
1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8"> 6 <title>ToDo List Vue-version</title> 7 8 <link rel="stylesheet" href="css/styles.css"> 9</head> 10 11<body> 12 <h2>ToDoリスト</h2> 13 <div id="app"> 14 <label><input type="radio" name="list" value="all" v-model="filter">すべて</label> 15 <label><input type="radio" name="list" value="active" v-model="filter">作業中</label> 16 <label><input type="radio" name="list" value="completed" v-model="filter">完了</label> 17 <p>ID コメント 状態</p> 18 19 <table> 20 <tr v-for="todo in filteredTodos"> 21 <td>{{ todo.id }}</td> 22 <td>{{ todo.title }}</td> 23 <td><button @click="statusChange(todo.id)">{{ todo.statusBtn }}</button></td> 24 <td><button @click="deleteTask(todo.id)">{{ todo.delBtn }}</button></td> 25 </tr> 26 </table> 27 <h2>新規タスクの追加</h2> 28 <form @submit.prevent="addTask"> 29 <input type="text" v-model="newTask"> 30 <input type="submit" value="追加" class="button"> 31 </form> 32 </div> 33 34 35 <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> 36 <script> 37 'use strict'; 38 39 new Vue({ 40 el: '#app', 41 data: { 42 id: 0, statusBtn: '', newTask: '', todos: [], filter: 'all' 43 }, 44 computed: { 45 filteredTodos() { 46 if (this.filter === 'all') { 47 return this.todos 48 } else if (this.filter === 'completed') { 49 return this.todos.filter((todo) => { 50 return todo.statusBtn === '完了' 51 }) 52 } else if (this.filter === 'active') { 53 return this.todos.filter((todo) => { 54 return todo.statusBtn === '作業中' 55 }) 56 } 57 } 58 }, 59 methods: { 60 addTask: function () { 61 let item = { 62 id: this.id++, title: this.newTask, statusBtn: '作業中', delBtn: '削除' 63 } 64 this.todos.push(item); 65 this.newTask = ''; 66 }, 67 statusChange: function (id) { 68 for (let todo of this.todos) { 69 if (todo.id === id) { 70 if (todo.statusBtn === '作業中') { 71 return todo.statusBtn = '完了' 72 } else { 73 return todo.statusBtn = '作業中' 74 } 75 break 76 } 77 } 78 }, 79 deleteTask: function (id) { 80 for (let todo of this.todos) { 81 if (todo.id === id) { 82 this.todos.splice(todo.id, 1); 83 break 84 } 85 } 86 } 87 } 88 }); 89 </script> 90</body> 91 92</html>
回答2件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。