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

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

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

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

Q&A

解決済

1回答

11124閲覧

[vue.js]子コンポーネントの値を親コンポーネントで合計したい

yoshiky

総合スコア105

Vue.js

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

0グッド

1クリップ

投稿2018/12/03 21:25

編集2018/12/05 03:15

お世話になります。
Vue.jsで子コンポーネントに入力値を合計した値を親コンポーネントに表示したいと思っています。子はv-forでループして複数あります。
具体的には、税抜金額を入力すると隣に税込金額が表示され、同時に税込合計金額が表示される、という感じです。
sample

現在、各入力欄を子コンポーネント、合計を親コンポーネント、という形にして実装していますが、
入力値の合計をどうやって親側で取得するのかわからずにいます。

途中ですが書いたソースです。

# ParentComp.vue <template> <div> <child-comp v-for="n in 5" :key="n"></child-comp> <p>ここに合計を出したい</p> </div> </template> <script> import childComp from '@/components/ChildComp' export default { name: 'parent-comp', data() { return { } }, components: { childComp } } </script>
# ChildComp.vue <template> <div> <input type="number" name="price" v-model="price"> <span>{{ priceWithTax }}</span> </div> </template> <script> export default { name: 'child-comp', data() { return { price: '' } }, computed: { priceWithTax() { return Math.floor(this.price * 1.08) } } } </script>

単純に子から親へ値を渡すのは$emitを使えばいいのですが、
子が複数あると、入力した子の値だけが渡ってしまい、親側で全合計になりません。

ご教示のほど、よろしくお願いいたします。


※追記
自己解決版

# ParentComp.vue <template> <div> <child-comp v-for="(item, idx) in items" :key="idx" v-bind:items="items" v-bind:idx="idx" /> <p>{{ total }}</p> </div> </template> <script> import ChildComp from '@/components/ChildComp' export default { name: 'parent-comp', data () { return { items: ['', '', '', '', ''], // 行追加/削除ボタンをつけるので仮置き total: 0 } }, updated() { let result = this.items.map(Number).reduce(function(sum, price) { return sum + price }) this.total = Math.floor(result * 1.08) }, methods: { addRow() { this.items.push('') } }, components: { ChildComp } } </script>
# ChildComp.vue <template> <div> <input v-model="items[idx]" type="text" class="input"/> <span>{{ priceWithTax(items[idx]) }}</span> </div> </template> <script> export default { name: 'child-comp', props: ['items', 'idx'], methods: { priceWithTax(price) { return Math.floor(price * 1.08) } } } </script>

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

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

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

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

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

guest

回答1

0

ベストアンサー

こんな感じでいかがでしょうか。

vue

1# ParentComp.vue 2 3<template> 4 <div> 5 <child-comp @caluclate="getSum"/> 6 <!-- ここに合計を出したい --> 7 <p>{{ sum_plice }}</p> 8 </div> 9</template> 10 11<script> 12import childComp from "@/components/ChildComp" 13 14export default { 15 data() { 16 return { 17 sum_plice: 0 18 } 19 }, 20 components: { 21 childComp 22 }, 23 methods: { 24 getSum(val) { 25 this.sum_plice = val 26 } 27 } 28} 29</script> 30

vue

1# ChildComp.vue 2 3<template> 4 <div> 5 <div v-for="i in 5" :key="i"> 6 <input type="number" v-model="price_list[i-1]"> 7 <span>{{ price_with_tax[i-1] }}</span> 8 </div> 9 </div> 10</template> 11 12<script> 13export default { 14 data() { 15 return { 16 price_list: [] 17 } 18 }, 19 computed: { 20 price_with_tax() { 21 return this.price_list.map(val => Math.floor(val * 1.08)) 22 } 23 }, 24 watch: { 25 price_with_tax(plice_list) { 26 let sum = 0 27 plice_list.map(val => { 28 sum += val 29 }) 30 this.$emit("caluclate", sum) 31 } 32 } 33} 34</script>

投稿2018/12/04 06:52

shou6

総合スコア305

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

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

yoshiky

2018/12/05 03:20 編集

返信が遅くなり失礼いたしました。実コードまで載せて頂き、ありがとうございます! 自分でも動くものができたのですが、ご提示頂いたソースのほうがすっきりしていて「Vueっぽい」と思いました。 computedで都度、税込処理を施した配列(price_list)を更新するところは思いついたのですが、 それをwatchで監視して合計値を親に渡す、というところが勉強になりました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問