お世話になります。
Vue.jsで子コンポーネントに入力値を合計した値を親コンポーネントに表示したいと思っています。子はv-for
でループして複数あります。
具体的には、税抜金額を入力すると隣に税込金額が表示され、同時に税込合計金額が表示される、という感じです。
現在、各入力欄を子コンポーネント、合計を親コンポーネント、という形にして実装していますが、
入力値の合計をどうやって親側で取得するのかわからずにいます。
途中ですが書いたソースです。
# 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>
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
0
こんな感じでいかがでしょうか。
# ParentComp.vue
<template>
<div>
<child-comp @caluclate="getSum"/>
<!-- ここに合計を出したい -->
<p>{{ sum_plice }}</p>
</div>
</template>
<script>
import childComp from "@/components/ChildComp"
export default {
data() {
return {
sum_plice: 0
}
},
components: {
childComp
},
methods: {
getSum(val) {
this.sum_plice = val
}
}
}
</script>
# ChildComp.vue
<template>
<div>
<div v-for="i in 5" :key="i">
<input type="number" v-model="price_list[i-1]">
<span>{{ price_with_tax[i-1] }}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
price_list: []
}
},
computed: {
price_with_tax() {
return this.price_list.map(val => Math.floor(val * 1.08))
}
},
watch: {
price_with_tax(plice_list) {
let sum = 0
plice_list.map(val => {
sum += val
})
this.$emit("caluclate", sum)
}
}
}
</script>
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.36%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる
2018/12/05 12:20 編集
自分でも動くものができたのですが、ご提示頂いたソースのほうがすっきりしていて「Vueっぽい」と思いました。
computedで都度、税込処理を施した配列(price_list)を更新するところは思いついたのですが、
それをwatchで監視して合計値を親に渡す、というところが勉強になりました。
ありがとうございました。