🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Vue.js

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

Vuetify.js

Vuetify.jsは、マテリアルデザインを基本とするVue.jsのCSSフレームワークです。多くのマテリアルデザインのコンポーネントを提供しており、あらゆるアプリケーションに対応可能。vue-cli用テンプレートがあり、簡単にページを作成できます。

Q&A

解決済

1回答

1565閲覧

vue.jsのコンポーネントで作成したインスタンスの計算結果を合算したい。

ittsu

総合スコア5

Vue.js

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

Vuetify.js

Vuetify.jsは、マテリアルデザインを基本とするVue.jsのCSSフレームワークです。多くのマテリアルデザインのコンポーネントを提供しており、あらゆるアプリケーションに対応可能。vue-cli用テンプレートがあり、簡単にページを作成できます。

0グッド

0クリップ

投稿2019/11/23 20:02

編集2019/11/23 20:09

前提・実現したいこと

v-forのリストデータで各々算出した小計を合計し、表示したい。

###質問詳細
vue.jsを用いて商品注文のリストを作成しています。
コンポーネントを用いて各々の品目の数量を増減出来るようにし、金額×数量を表示し、
コンポーネントから作成したインスタンスをv-forを用いて商品リストを複数作成するところまでは出来たのですが、
それらの小計を足し合わせて合計金額を表示する段階で躓いています。
数量を増減する毎に合計金額にも反映されるようにするにはどのすればよいかご教示ください。

該当のソースコード

####components/Item.vue

Vue

1<template> 2 <v-card> 3 <v-list-item> 4 <v-list-item-content> 5 <v-list-item-title class="headline mb-2">{{name}}</v-list-item-title> 6 <v-list-item-text>¥{{price}} * {{count}}</v-list-item-text> 7 <v-list-item-text v-show="subtotal>0">¥{{subtotal}}</v-list-item-text> 8 </v-list-item-content> 9 </v-list-item> 10 11 <v-card-actions> 12 <v-btn @click="Increment">+1</v-btn> 13 <v-btn @click="Decrement">-1</v-btn> 14 <v-btn @click="Reset">Reset</v-btn> 15 </v-card-actions> 16 </v-card> 17</template> 18 19<script> 20export default { 21 props: { 22 name: { 23 type: String, 24 default: null 25 }, 26 price: { 27 type: Number, 28 default: 10 29 }, 30 count: { 31 type: Number, 32 default: 0 33 } 34}, 35 methods: { 36 Increment: function() { 37 this.count += 1; 38 }, 39 Decrement: function() { 40 if (this.count > 0) { 41 this.count -= 1; 42 } 43 }, 44 Reset: function() { 45 this.count = 0; 46 } 47 }, 48 computed: { 49 subtotal: function() { 50 return this.price * this.count; 51 } 52 } 53}; 54</script>

####components/ItemList.vue

vue

1<template> 2 <ul> 3 <v-layout wrap> 4 <Item 5 v-for="item in list" 6 :key="item.id" 7 :name="item.name" 8 :price="item.price" 9 :count="item.count" 10 ></Item> 11 </v-layout> 12 </ul> 13</template> 14 15<script> 16import Item from "./Item"; 17 18export default { 19 components: { 20 Item 21 }, 22 data: function() { 23 return { 24 list: [ 25 { 26 id: 1, 27 name: "商品A", 28 price: 850, 29 count: 0 30 }, 31 { 32 id: 2, 33 name: "商品B", 34 price: 900, 35 count: 0 36 } 37 }; 38 }, 39 computed: { 40 total: function() { 41 let sum = 0; 42 return this.item.subtotal.reduce((sum, item) => sum + item.subtotal, 0); 43 } 44 } 45}; 46</script>

試したこと

算出プロパティにてreduceを用いて合計金額を計算出来ないか試みましたが、うまくいかず。
components/ItemList.vueの算出プロパティが試したみたそのものです。

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

Nuxt.js,Vuetifyを利用しています。

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

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

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

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

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

guest

回答1

0

ベストアンサー

propsで渡した変数に代入するとワーニング出るとおもうのですが…というのはさておき
オブジェクト渡すことで親へ状態変化を伝えれるのを利用して
単方向のデータフロー

ItemList.vue

vue

1<template> 2 <ul> 3 <v-card> 4 <Item 5 v-for="item in list" 6 :key="item.id" 7 :listItem="item" 8 ></Item> 9 {{ total }} 10 </v-card> 11 </ul> 12</template> 13 14<script> 15import Item from "./Item"; 16 17export default { 18 components: { 19 Item 20 }, 21 data: function() { 22 return { 23 list: [ 24 { 25 id: 1, 26 name: "商品A", 27 price: 850, 28 count: 0 29 }, 30 { 31 id: 2, 32 name: "商品B", 33 price: 900, 34 count: 0 35 } 36 ], 37 total: 0, 38 } 39 }, 40 watch: { 41 list: { 42 handler: function() { 43 let sum = 0; 44 this.total = this.list.reduce((sum, item) => sum + (item.price * item.count), 0); 45 }, 46 deep: true, 47 } 48 } 49}; 50</script>

Item.vue

vue

1<template> 2 <v-card> 3 <v-list-item> 4 <v-list-item-content> 5 {{listItem.name}} 6 ¥{{listItem.price}} * {{listItem.count}} 7 <div v-show="subtotal>0">¥{{subtotal}}</div> 8 </v-list-item-content> 9 </v-list-item> 10 11 <v-card-actions> 12 <v-btn @click="Increment">+1</v-btn> 13 <v-btn @click="Decrement">-1</v-btn> 14 <v-btn @click="Reset">Reset</v-btn> 15 </v-card-actions> 16 </v-card> 17</template> 18 19<script> 20export default { 21 props: { 22 listItem: { 23 type: Object, 24 default: {} 25 }, 26 }, 27 methods: { 28 Increment: function() { 29 this.listItem.count += 1; 30 }, 31 Decrement: function() { 32 if (this.listItem.count > 0) { 33 this.listItem.count -= 1; 34 } 35 }, 36 Reset: function() { 37 this.listItem.count = 0; 38 } 39 }, 40 computed: { 41 subtotal: function() { 42 return this.listItem.price * this.listItem.count; 43 } 44 } 45}; 46</script>

※一部タグがどうにも動かなかったので外してます(v-list-item-textやらv-layout)

投稿2019/11/26 06:23

rururu3

総合スコア5545

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

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

ittsu

2019/11/29 16:07

うまく動作しました! listItemの整形も参考となりました。ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問