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

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

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

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

Vue CLI

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

Q&A

0回答

216閲覧

todoの編集フォーム(子コンポーネント)での値の表示と更新が上手くいかない。

keisei-001

総合スコア15

Vue.js

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

Vue CLI

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

0グッド

0クリップ

投稿2020/01/03 01:40

前提・実現したいこと

todoアプリをvue.jsを使って作成しており、一旦は親コンポーネントとなるApp.vueを使って作成してきました。
ここから角パーツをコンポーネントごとに分ける作業に入ったところなのですが編集フォームに入った段階でうまく行かない状況です。

App.vue(こちらが全体的な親コンポーネント)

<template> <div class="todo"> <TopHeader :todos="todos" :calc-day="calcDay" :remaining="remaining"></TopHeader> <div class="box"> <div class="todo-left"> <!-- todoがあるときに表示する。 --> <div v-show="todos.length" class="todo-container"> <div class="btns"> <!-- 完了したtodoを削除 --> <button @click="purgeItem" class="purge">purge</button> <button @click="allDelete" class="delete">all delete</button> </div> <ul class="todo-list"> <li v-for="(todo, index) in todos" :key="index"> <p class="data">Posted date:{{todo.today}}</p> <p class="deadline" :class="{hurry: todo.isDone}">dead-line:{{todo.deadline}}</p> <div class="change-btns"> <span class="edit" @click="editForm(index)">edit</span> <span class="delete" @click="deleteItem(index)">delete</span> </div> <p class="title"> <label class="text"> <input type="checkbox" class="check" v-model="todo.isDone" /> <span :class="{done: todo.isDone}">{{todo.title}}</span> </label> </p> <p class="content">{{todo.content}}</p> </li> </ul> </div> <!-- todoがないときに表示する。 --> <ul class="no-todo-list" v-show="!todos.length"> <li>No todo!</li> </ul> </div> <!--/ todo-left --> <div class="todo-right"> <AddForm :todos="todos" :calc-day="calcDay" :edit="edit"></AddForm> <EditForm :calc-day="calcDay" :todos="todos" :props-edit="edit" :props-new-title="newTitle" :props-new-content="newContent" :props-selected="selected" :deadlines="deadlines" :editTargetTask="editTargetTask" :props-todos="todos" ></EditForm> </div> <!-- /todo-right --> <!-- :props-edit="edit" --> </div> </div> </template> <script> import TopHeader from "./component/TopHeader.vue"; import AddForm from "./component/AddForm.vue"; import EditForm from "./component/EditForm.vue"; export default { components: { TopHeader, AddForm, EditForm }, data() { return { day: "", todos: [], newTitle: "", newContent: "", selected: 0, editTargetTask: 0, deadlines: { "--": "", "Within 1 day": 1, "Within 3 days": 3, "Within 5 days": 5, "Within 10 days": 10, "Within 30 days": 30, "Within 60 days": 60, "Within 100 days": 100 }, edit: false, num: 10 }; }, computed: { // 残ったtodoの数を表示 remaining() { return this.todos.filter(function(todo) { return !todo.isDone; }); }, // 終了したtodoの数を表示 finish() { return this.todos.filter(function(todo) { return todo.isDone; }); } }, methods: { // 日付のフォーマットとtodoの締め切りを設定する日数計算の関数 calcDay(day, created_at) { var today; if (created_at == null || created_at == "") { today = new Date(); } else { today = new Date(created_at); } today.setDate(today.getDate() + day); var year = today.getFullYear(); var month = today.getMonth() + 1; day = today.getDate(); var formatDay = year + "/" + month + "/" + day; return formatDay; }, // todoの削除 deleteItem(index) { confirm("delete ok?") ? this.todos.splice(index, 1) : true; }, allDelete() { confirm("all delete ok?") ? (this.todos = []) : true; }, /* v-forのindexの値を取得して関数でターゲットとするtodoのデータを取得、 v-modelをformに設置している使ってデータの値を書き換える関数*/ editForm(index) { //編集をするためのフォームへの切り替え this.edit = true; this.newTitle = this.todos[index].title; this.newContent = this.todos[index].content; this.selected = this.todos[index].selected; this.editTargetTask = index; }, // 終了したタスクのみ削除 purgeItem() { this.finish.length === 0 ? window.alert("No checked") : confirm("purgeItem delete ok?") ? (this.todos = this.remaining) : true; } }, // todosを監視し、データを保存させている watch: { todos: { handler() { localStorage.setItem("todos", JSON.stringify(this.todos)); }, deep: true } }, // ライフサイクルのマウントされたタイミングでtodoを呼び出す。 mounted() { this.todos = JSON.parse(localStorage.getItem("todos")) || []; } }; </script>

editForm.vue(編集用の子コンポーネント)

<template> <form v-show="propsEdit" @submit.prevent="editItem"> <p class="title"> <label for="title">TITLE</label> <input type="text" id="title" v-model="newTitle"> </p> <p class="content"> <label for="content">content</label> <textarea cols="30" id="content" rows=" 10" v-model="propsNewContent"></textarea> </p> <p class="deadline"> <label for="edit-deadline">deadline</label> <select id="edit-deadline" v-model="propsSelected" options="deadlines"> <option :value="value" v-for="(value, key) in deadlines" :key=value>{{key}}</option> </select> </p> <p class="btn"> <input type="submit" class="edit" value="edit"> </p> </form><!-- /editform --> </template> <script> export default { props: {/*これはバリデーションを定義した書き方*/ calcDay: Function, propsTodos: Array, propsEdit: Boolean, propsNewTitle: String, propsNewContent: String, propsSelected: Number, deadlines: Object, editTargetTask: Number, }, data(){ return { selected: this.propsSelected, newTitle: this.propsNewTitle, newContent: this.propsNewContent, edit: this.propsEdit, todo: this.propsTodos, } }, methods: { // 編集フォームの内容を代入し変更する。 editItem(){ if (this.propsNewTitle == "" || this.propsNewContent == "" || this.propsSelected == "") { return false; } console.log(this.propsNewTitle) console.log(this.newTitle) this.propsTodos[this.editTargetTask].title = this.propsNewTitle, this.propsTodos[this.editTargetTask].content = this.propsNewContent, this.propsTodos[this.editTargetTask].deadline = this.calcDay(this.propsSelected, this.propsTodos[this.editTargetTask].today), this.edit = false; } } } </script>

試したこと❶

親コンポーネントからpropsで各値を受け取る
????
EditForm.vueの各input要素にpropsの値をv-modelに設定して値を取得
????
編集をする。
????
console.logで確認すると上書きをするなと怒られる

試したこと❷

親コンポーネントからpropsで各値を受け取る
????
一旦はdataにpropsで受け取った値を登録する。
????
登録した値をv-model設定する
????
editフォームを表示させても値を表示出来ていない。

気づき

editItemメソッドを発火させてデバッグしてみる。

console.log(this.propsNewTitle) //todoに入っていた中身を取得出来ている。 console.log(this.newTitle) //input要素に入れて入力すると値は取得出来ているが初期表示はしてくれない。

あとは下記のようにtodoの中身を書き換えていけばいいと思っているんですがうまく行かない状況です。

this.propsTodos[this.editTargetTask].title = this.newTitle

どうかご教授よろしくお願いいたします。

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

本番環境
https://todo-app02.netlify.com/
git hub
https://github.com/gonta1026/vue-todo02
version
@vue/cli 4.1.1

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問