Vue: как обновить общую цену корзины, когда пользователь увеличивает элемент в дочернем компоненте - PullRequest
0 голосов
/ 24 октября 2019

Итак, я создаю эту страницу корзины в Vue. Я просто не понимаю, как обновить общую цену страницы корзины, когда количество дочерних компонентов товара увеличивается или уменьшается. Конечно, если количество компонентов возрастет, общая цена тоже должна увеличиться.

Вот мой родительский компонент корзины:

<template>
  <div class="cart-container">
    <h1 class="cart-title-page">Keranjang Anda</h1>
    <div class="cart-item-container">
      <cart-item v-for="(data, i) in cartData" :item="data" :key="i" />
    </div>
    <div class="cart-total-wrapper">
      <div class="total-text-wrapper">
        <p>Total</p>
      </div>
      <div class="total-amount-wrapper">
        <p>Rp. 150.000.000</p>
      </div>
    </div>
  </div>
</template>

<script>
import CartItem from '@/components/cart-item'

export default {
  data() {
    return {
      cartData: [
        {
          product_name: 'vario ZS1',
          price: 1000000,
          url_thumbnail: 'https://cdn3.imggmi.com/uploads/2019/10/8/9e27ca9046031f6f21850be39b379075-full.png',
          color: '#fff'
        },
        {
          product_name: 'vario ZS1',
          price: 1000000,
          url_thumbnail: 'https://cdn3.imggmi.com/uploads/2019/10/8/9e27ca9046031f6f21850be39b379075-full.png',
          color: '#fff'
        },
        {
          product_name: 'vario ZS1',
          price: 1000000,
          url_thumbnail: 'https://cdn3.imggmi.com/uploads/2019/10/8/9e27ca9046031f6f21850be39b379075-full.png',
          color: '#fff'
        }
      ]
    }
  },
  methods: {
    getAllCartItem () {
      this.$store.dispatch('cart/checkCartItem')
      this.cartData = this.$store.state.cart.cartItem
    }
  },
  created () {
    this.getAllCartItem ()
  },
  components: {
    'cart-item': CartItem
  }
}
</script>

это дочерний компонент моей корзины:

<template>
  <div class="root-cart-item">
    <div class="container-cart-left">
      <div class="cart-img-wrapper">
          <img :src="item.url_thumbnail" />
      </div>
      <div class="cart-title-wrapper">
        <div class="title-wrapper">
          <h3>{{ getProductbrand }}</h3>
          <p>{{ item.product_name }}</p>
        </div>
      </div>
    </div>

    <div class="container-cart-right">
      <div class="cart-amount-wrapper">
        <number-input v-model="singleCart.amount" :min="1" :max="singleCart.stok" inline center controls></number-input>
      </div>
      <div class="cart-price-wrapper">
        <p>{{  getProductTotalPrice  }}</p>
      </div>
      <div class="cart-delete-wrapper">
        <img src="../assets/delete.svg"/>
      </div>
    </div> 

  </div>
</template>

<script>
import ProductImage from './product-image'
import VueNumberInput from '@chenfengyuan/vue-number-input';

export default {
  props: {
    item: {
      type: Object,
      required: true
    }
  },
  data () {
    return {
      singleCart: {
        stok: 15,
        amount: 1,
        totalPrice: 0
      }
    }
  },
  computed: {
    getProductbrand: function () {
      let splittedName = this.item.product_name.split(' ')
      return splittedName[0]
    },
    getProductTotalPrice: function () {
      var x = this.singleCart.totalPrice.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ".")
      var totalPrice = `Rp. ${x}`
      return totalPrice
    }
  },
  watch: {
    'singleCart.amount': {
      handler: function () {
        this.singleCart.totalPrice = this.singleCart.price * this.singleCart.amount
      },
      deep: true
    }
  },
  components: {
    'product-image': ProductImage,
    'number-input': VueNumberInput
  }
}
</script>>

и если кому-то интересно, это мой магазин:

const state = {
  cartItem: []
}

const getters = {
  getAllCartItem: (state) => {
    return state.cartItem
  }
}

const mutations = {
  updateCartItem: (state, cart) => {
    state.cartItems = cart
  }
}

const actions = {
  checkCartItem: ({ commit }) => {
    let item = JSON.parse(localStorage.getItem('cart'))
    if (cart) {
      commit('updateCartItem', item)
    } 
  }
}

export default {
  namespaced: true,
  state,
  getters,
  actions,
  mutations
}

Как я уже сказал, проблема должна быть довольно простой, мне просто нужно обновить класс CSS .total-amount-wrapper в родительском. компонент, когда количество в дочернем компоненте увеличивается или уменьшается. Общая стоимость в дочернем компоненте корзины-элемента работает, мне просто нужно найти способ подсчитать каждую общую цену в дочернем компоненте корзины-элемента и показать ее в родительском компоненте.

1 Ответ

1 голос
/ 24 октября 2019

Для обновления родительского элемента вы должны использовать v-модель подхода или $ emit .

. В вашем коде вы должны обновить input доиспользуйте v-model или вы должны $emit событие при изменении цены.

Первое простое, и вы должны следовать руководству, которое вы найдете по ссылке выше, второе ниже.

Дочерний компонент

watch: {
    'singleCart.amount': {
      handler: function () {
        this.singleCart.totalPrice = this.singleCart.price * this.singleCart.amount
        this.$emit("priceChanged", this.singleCart.totalPrice);
      },
      deep: true
    }
  }

Родитель

<template>

..

 <div class="cart-item-container">
      <cart-item v-for="(data, i) in cartData" :item="data" :key="i" 
              @priceChanged="onPriceChanged" />
 </div>

</template>

<script>

methods: {
..
     onPriceChanged(value) {
         this.total += value;
     }
}


</scritp>
...