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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Vue.js

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

1回答

1730閲覧

Uncaught TypeError: Cannot read property 'value' of undefined の解決方法

ransan_33

総合スコア15

Vue.js

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

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

0クリップ

投稿2019/06/02 11:01

編集2019/06/04 07:00

前提・実現したいこと

Vue.jsでTodoアプリでのtaskの追加できるようにする方法
valueの定義の仕方

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

Uncaught TypeError: Cannot read property 'value' of undefined

該当のソースコード

HTML

1<!DOCTYPE html> 2<html lang="ja"> 3 4<head> 5 <meta charset="UTF-8" /> 6 <title>Todo</title> 7</head> 8 9<body> 10 <div id="app"> 11 <h1>ToDo リスト</h1> 12 13 <label v-for="label in options"> 14 <input type="radio" v-model="current" v-bind:value="label.value" />{{label.label }} 15 </label> 16 17 ({{ computedTodos.length }} 件を表示) 18 19 <table> 20 <thead v-pre> 21 <tr> 22 <th class="id">ID</th> 23 <th class="comment">コメント</th> 24 <th class="state">状態</th> 25 <th class="button">-</th> 26 </tr> 27 </thead> 28 <tbody> 29 <tr v-for="item in computedTodos" v-bind:key="item.id" v-bind:class="{done:item.state}"> 30 <th>{{ item.id }}</th> 31 <td>{{ item.comment }}</td> 32 <td class="state"> 33 <button v-on:click="doChangeState(item)"> 34 {{ labels[item.state] }} 35 </button> 36 </td> 37 <td class="button"> 38 <button v-on:click.ctrl="doRemove(item)"> 39 削除 40 </button> 41 </td> 42 </tr> 43 </tbody> 44 </table> 45 <p>*削除ボタンはコントロールキーを押しながらクリックしてください</p> 46 47 <h2>新しい作業の追加</h2> 48 <form class="add-form" v-on:submit.prevent="doAdd"> 49 コメント<input type="text" ref="comment" /> 50 <button type="submit" id="submit">追加</button> 51 </form> 52 </div> 53 54 <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.18/vue.min.js"></script> 55 <script src="https://cdn.jsdelivr.net/npm/lodash@4.17.5/lodash.min.js"></script> 56 <script> 57 var STORAGE_KEY = "todos-vuejs-demo"; 58 var todoStorage = { 59 fetch: function () { 60 var todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || "[]"); 61 todos.forEach(function (todo, index) { 62 todo.id = index; 63 }); 64 todoStorage.uid = todos.length; 65 return todos; 66 }, 67 save: function (todos) { 68 localStorage.setItem(STORAGE_KEY, JSON.stringify(todos)); 69 } 70 }; 71 new Vue({ 72 el: "#app", 73 data: { 74 todos: [], 75 current: -1, 76 options: [{ 77 value: -1, 78 label: "全て" 79 }, 80 { 81 value: 0, 82 label: "作業中" 83 }, 84 { 85 value: 1, 86 label: "完了" 87 } 88 ] 89 }, 90 91 computed: { 92 computedTodos: function () { 93 return this.todos.filter(function (el) { 94 return this.current < 0 ? true : this.current === el.state; 95 }, this); 96 }, 97 98 labels() { 99 return this.options.reduce(function (a, b) { 100 return Object.assign(a, { 101 [b.value]: b.label 102 }); 103 }, {}); 104 } 105 }, 106 107 watch: { 108 todos: { 109 handler: function (todos) { 110 todoStorage.save(todos); 111 }, 112 deep: true 113 } 114 }, 115 created() { 116 this.todos = todoStorage.fetch(); 117 }, 118 119 methods: { 120 doAdd: function (event, value) { 121 let comment = this.$refs.comment 122 if (!comment.value.length) { 123 return; 124 } 125 this.todos.push({ 126 id: todoStorage.uid++, 127 comment: comment.value, 128 state: 0 129 }); 130 comment.value = "" 131 }, 132 doChangeState: function (item) { 133 item.state = !item.state ? 1 : 0; 134 }, 135 doRemove: function (item) { 136 let index = this.todos.indexOf(item); 137 this.todos.splice(index, 1); 138 } 139 } 140 }); 141 </script> 142 <style> 143 body { 144 text-align: center; 145 } 146 </style> 147</body> 148 149</html>

試したこと

ひたすら、調べてもどこの部分を直したらいいのかわからなかったので、お願いします

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

html
Vue.js
ここにより詳細な情報を記載してください。

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

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

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

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

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

karamarimo

2019/06/02 11:39

object.assign とありますが Object.assign の間違いでしょうか。
guest

回答1

0

ベストアンサー

ref属性は直接子コンポーネントにアクセスするときに
使用するものなので使い方が間違っています。
子コンポーネントインスタンスと子要素へのアクセス

今回のtodoならdataにcommentを追加するだけで機能します。

あとobject.assignでは機能しないので
正しくObject.assignと記述が必要です。

html

1<!DOCTYPE html> 2<html lang="ja"> 3<head> 4<meta charset="UTF-8" /> 5<title>Todo</title> 6<style> 7body { 8 text-align: center; 9} 10</style> 11</head> 12<body> 13<div id="app"> 14 <h1>ToDo リスト</h1> 15 <label v-for="label in options"> 16 <input type="radio" v-model="current" v-bind:value="label.value" />{{ 17 label.label 18 }} 19 </label> 20 ({{ computedTodos.length }} 件を表示) 21 <table> 22 <thead v-pre> 23 <tr> 24 <th class="id">ID</th> 25 <th class="comment">コメント</th> 26 <th class="state">状態</th> 27 <th class="button">-</th> 28 </tr> 29 </thead> 30 <tbody> 31 <tr 32 v-for="item in computedTodos" 33 v-bind:key="item.id" 34 v-bind:class="{done:item.state}" 35 > 36 <th>{{ item.id }}</th> 37 <td>{{ item.comment }}</td> 38 <td class="state"> 39 <button v-on:click="doChangeState(item)"> 40 {{ labels[item.state] }} 41 </button> 42 </td> 43 <td class="button"> 44 <button v-on:click.ctrl="doRemove(item)"> 45 削除 46 </button> 47 </td> 48 </tr> 49 </tbody> 50 </table> 51 <p>*削除ボタンはコントロールキーを押しながらクリックしてください</p> 52 53 <h2>新しい作業の追加</h2> 54 <form class="add-form" v-on:submit.prevent="doAdd"> 55 コメント<input type="text" v-model="comment" /> 56 <button type="submit" id="submit">追加</button> 57 </form> 58</div> 59<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.18/vue.min.js"></script> 60<script src="https://cdn.jsdelivr.net/npm/lodash@4.17.5/lodash.min.js"></script> 61<script> 62var STORAGE_KEY = "todos-vuejs-demo"; 63var todoStorage = { 64 fetch: function() { 65 var todos = JSON.parse(localStorage.getItem(STORAGE_KEY) || "[]"); 66 todos.forEach(function(todo, index) { 67 todo.id = index; 68 }); 69 todoStorage.uid = todos.length; 70 return todos; 71 }, 72 save: function(todos) { 73 localStorage.setItem(STORAGE_KEY, JSON.stringify(todos)); 74 } 75}; 76new Vue({ 77 el: "#app", 78 data: { 79 todos: [], 80 comment: "", 81 current: -1, 82 options: [ 83 { 84 value: -1, 85 label: "全て" 86 }, 87 { 88 value: 0, 89 label: "作業中" 90 }, 91 { 92 value: 1, 93 label: "完了" 94 } 95 ] 96 }, 97 computed: { 98 computedTodos: function() { 99 return this.todos.filter(function(el) { 100 return this.current < 0 ? true : this.current === el.state; 101 }, this); 102 }, 103 104 labels() { 105 return this.options.reduce(function(a, b) { 106 return Object.assign(a, { 107 [b.value]: b.label 108 }); 109 }, {}); 110 } 111 }, 112 watch: { 113 todos: { 114 handler: function(todos) { 115 todoStorage.save(todos); 116 }, 117 deep: true 118 } 119 }, 120 created() { 121 this.todos = todoStorage.fetch(); 122 }, 123 methods: { 124 doAdd: function(event, value) { 125 console.log(this.comment); 126 if (!this.comment) { 127 return; 128 } 129 this.todos.push({ 130 id: todoStorage.uid++, 131 comment: this.comment, 132 state: 0 133 }); 134 this.comment = ""; 135 }, 136 doChangeState: function(item) { 137 item.state = !item.state ? 1 : 0; 138 }, 139 doRemove: function(item) { 140 let index = this.todos.indexOf(item); 141 this.todos.splice(index, 1); 142 } 143 } 144}); 145</script> 146</body> 147</html> 148

投稿2019/06/02 12:53

yasutomi

総合スコア2937

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問