Как найти общую сумму товаров в корзине?

Как правильно организовать вложенность четырех компонентов во Vue: App.vue, Drawer.vue, CartItemList.vue и CartItem.vue?
  • 29 июня 2024 г. 17:32
Ответы на вопрос 2
1. Для того чтобы найти общую сумму товаров в корзине, необходимо пройти по всем товарам в корзине и сложить их цены. В каждом товаре должно быть указано его количество и цена. Например, если у вас есть массив объектов в корзине, вы можете пройти по нему с помощью метода reduce и сложить цену товара умноженную на его количество:

```javascript
const cartItems = [
  { name: 'item1', price: 10, quantity: 2 },
  { name: 'item2', price: 20, quantity: 1 },
  { name: 'item3', price: 5, quantity: 3 },
];

const totalSum = cartItems.reduce((acc, item) => {
  return acc + (item.price * item.quantity);
}, 0);

console.log(totalSum); // выводит общую сумму товаров в корзине
```

2. Для организации вложенности компонентов во Vue следует создать иерархию компонентов:

- App.vue будет основным компонентом, содержащим главную логику приложения и необходимые данные.
- Drawer.vue будет компонентом, отвечающим за отображение боковой панели (например, корзины) в приложении.
- CartItemList.vue будет компонентом, отображающим список товаров в корзине и передающим данные о товарах в компоненты CartItem.vue.
- CartItem.vue будет компонентом, отображающим отдельный товар в корзине и получающим данные о товаре из родительского компонента CartItemList.vue.

Пример структуры компонентов во Vue:

```html
<!-- App.vue -->
<template>
  <div>
    <Drawer />
  </div>
</template>

<script>
import Drawer from './components/Drawer.vue';

export default {
  components: {
    Drawer,
  },
};
</script>

<!-- Drawer.vue -->
<template>
  <div>
    <CartItemList />
  </div>
</template>

<script>
import CartItemList from './CartItemList.vue';

export default {
  components: {
    CartItemList,
  },
};
</script>

<!-- CartItemList.vue -->
<template>
  <div>
    <CartItem v-for="item in cartItems" :key="item.id" :item="item" />
  </div>
</template>

<script>
import CartItem from './CartItem.vue';

export default {
  components: {
    CartItem,
  },
  data() {
    return {
      cartItems: [
        { id: 1, name: 'item1', price: 10 },
        { id: 2, name: 'item2', price: 20 },
      ],
    };
  },
};
</script>

<!-- CartItem.vue -->
<template>
  <div>
    <p>{{ item.name }} - ${{ item.price }}</p>
  </div>
</template>

<script>
export default {
  props: {
    item: Object,
  },
};
</script>
```

Таким образом, компоненты CartItemList.vue и CartItem.vue будут вложены в компонент Drawer.vue, а компонент Drawer.vue будет вложен в главный компонент App.vue. Каждый компонент будет отвечать за свою часть интерфейса и логику, что упростит поддержку и разработку приложения.
item.isAdded = true

Это как, одни и те же объекты используются и в списке товаров, и в корзине? Можете начинать думать, как будете переделывать, чтобы такой ерунды не было. Ну а пока попробуем заставить ваш говнокод вести себя должным образом :

const quantity = ref(1)

Что, закрыли корзину и потеряли данные о количестве? Пусть количество будет свойством элемента массива, представляющего корзину, соответственно, приходит сверху, и туда же отправляется новое:

const quantity = defineModel('quantity');

В родителе ловим это новое количество и дёргаем метод обновления:

<CartItem
  v-for="n in cart"
  v-bind="n"
  :key="n.id"
  @update:quantity="updateQuantity(n, $event)"
  @remove="removeFromCart(n)"
/>

Откуда этот метод возьмётся? Оттуда же, откуда и методы добавления (этот вам придётся поправить самостоятельно, при добавлении в корзину надо задавать количество по умолчанию, типа единица) и удаления, делаем по аналогии:

const updateQuantity = (item, quantity) => item.quantity = quantity;

Ну и наконец, исправленный расчёт суммы, цену надо умножать на количество:

const totalPrice = computed(() => cart.value.reduce((acc, n) => acc + n.price * n.quantity, 0));
Похожие вопросы