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

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

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

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

JavaScript

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

Q&A

0回答

511閲覧

[Vue] 子コンポーネントでpropsを自由に扱いたい

kotarofunyu

総合スコア23

Vue.js

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

JavaScript

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

0グッド

0クリップ

投稿2020/12/23 13:40

前提・実現したいこと

一覧ページコンポーネント(親)があり、一覧表示されているデータにそれぞれ「編集」というボタンがあります。
編集ボタンをクリックすると、フォームコンポーネント(子)がダイアログで表示されます。
その際、一覧ページコンポーネント(親)はフォームコンポーネント(子)へクリックしたデータの情報をpropsで渡します。
バックエンドAPIへのPUTは、フォームコンポーネントが行うため、フォームコンポーネントでpropsを自由に扱いたいのですが、
こういった実装はおかしいのでしょうか...?以下にコードを掲載します。
子コンポーネントで受け取ったpropsを、子コンポーネントのdataプロパティに代入してリアクティブな感じにできると良いですが、
最初のみしか動作しないので...。
子コンポーネントのcomputedで入力フォームとバインディングしているのですが、変更があった場合にしかセッターでdataにセットできないんですよね...。

vue

1// 一覧ページコンポーネント 2<template> 3 <v-data-table 4 :headers="headers" 5 :items="items" 6 item-key="id" 7 :items-per-page="7" 8 > 9 <template v-slot:item.action="{ item }"> 10 <v-btn fab small color="indigo" outlined @click="editItem(item)"> 11 <v-icon>mdi-pencil</v-icon> 12 </v-btn> 13 <v-btn 14 fab 15 small 16 color="indigo" 17 outlined 18 class="mx-1" 19 @click="deleteData(item.id)" 20 > 21 <v-icon>delete</v-icon> 22 </v-btn> 23 </template> 24 <router-link to="/record/" + item.id>detail</router-link> 25 </v-data-table> 26 <FormModal 27 :visible="dialog" 28 :idData="editedItem.id" 29 :dateData="editedItem.date" 30 :weightData="editedItem.weight" 31 :commentData="editedItem.comment" 32 @close="dialog = false" 33 /> 34</template> 35 36<script> 37export default { 38 name: "Index", 39 components: { 40 FormModal, 41 }, 42 data() { 43 return { 44 detailDialog: false, 45 dialog: false, 46 editedItem: { 47 id: 0, 48 weight: 0, 49 date: "", 50 comment: "", 51 }, 52 editedIndex: -1, 53 }; 54 }, 55 mounted() { 56 this.$store.dispatch("getWeightsDatas"); 57 }, 58 methods: { 59 editItem(item) { 60 this.editedIndex = this.items.indexOf(item); 61 this.editedItem = Object.assign({}, item); 62 this.dialog = true; 63 console.log(this.editedItem); 64 }, 65 }, 66}; 67</script> 68

Vue

1<template v-slot:append> 2 <v-dialog v-model="show" persistent :retain-focus="false" max-width="600px"> 3 <v-card id="form"> 4 <v-card-title>フォーム</v-card-title> 5 <v-card-text> 6 <v-form ref="form"> 7 <v-date-picker 8 v-model="innerDate" 9 label="記録日" 10 :rules="[required]" 11 ></v-date-picker> 12 <v-text-field 13 v-model.number="innerWeight" 14 label="入力必須で文字数制限のあるテキストフィールド" 15 placeholder="体重の数値" 16 type="number" 17 :rules="[required]" 18 > 19 </v-text-field> 20 <v-textarea 21 v-model="innerComment" 22 label="コメント" 23 clearable 24 filled 25 shaped 26 counter 27 > 28 </v-textarea> 29 <p v-show="notNumber">数値ではありません</p> 30 <v-divider></v-divider> 31 <v-card-actions> 32 <v-btn test v-on:click="submit">送信する</v-btn> 33 <span v-if="success">投稿しました!</span> 34 </v-card-actions> 35 <v-spacer></v-spacer> 36 <v-card-actions> 37 <v-btn color="grey" text @click.stop="show = false"> 閉じる </v-btn> 38 </v-card-actions> 39 </v-form> 40 </v-card-text> 41 </v-card> 42 </v-dialog> 43</template> 44 45<script> 46import firebase from "@/plugins/firebase"; 47export default { 48 name: "FormModal", 49 props: { 50 visible: { 51 type: Boolean, 52 default: false, 53 required: false, 54 }, 55 idData: { 56 type: Number, 57 default: null, 58 required: true, 59 }, 60 dateData: { 61 type: String, 62 default: "", 63 required: false, 64 }, 65 weightData: { 66 type: Number, 67 default: null, 68 reqiured: false, 69 }, 70 commentData: { 71 type: String, 72 default: "", 73 required: false, 74 }, 75 }, 76 data() { 77 return { 78 id: null, 79 date: "", 80 weight: null, 81 comment: "", 82 success: false, 83 }; 84 }, 85 computed: { 86 show: { 87 get() { 88 return this.visible; 89 }, 90 set(value) { 91 if (!value) { 92 this.$emit("close"); 93 } 94 }, 95 }, 96 innerId: { 97 get () { 98 return this.$props.idData 99 }, 100 set (newValue) { 101 this.id = newValue 102 } 103 }, 104 innerDate: { 105 get () { 106 return this.$props.dateData 107 }, 108 set (newValue) { 109 this.date = newValue 110 } 111 }, 112 innerWeight: { 113 get () { 114 return this.$props.weightData 115 }, 116 set (newValue) { 117 this.weight = newValue 118 } 119 }, 120 innerComment: { 121 get () { 122 return this.$props.commentData 123 }, 124 set (newValue) { 125 this.comment = newValue 126 } 127 }, 128 notNumber() { 129 const value = Number(this.weight); 130 return Number.isNaN(value); 131 }, 132 }, 133 methods: { 134 submit() { 135 if (this.$refs.form.validate()) { 136 console.log(this.hogepiyo); 137 this.axios({ 138 method: this.$props.httpMethod, 139 url: "http://localhost:3000/weights/" + this.id, 140 params: { 141 date: this.date, 142 weight: parseFloat(this.weight), 143 comment: this.comment 144 }, 145 }) 146 .then( 147 function (response) { 148 this.$emit("close"); 149 }.bind(this) 150 ) 151 } else { 152 this.success = false; 153 } 154 }, 155 }, 156}; 157</script>

試したこと

子コンポーネントのcomputedで以下を行う=>しかしデータを変更しなかった場合にセッターが作動しないので、変更した値しか扱えない。

Javascript

1computed: { 2 innerId: { 3 get (){ return this.$props.idData; }, 4 set (value){ this.id = value; } 5 } 6}

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

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

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

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

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

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

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問