0๐
โ
I solved my problem by using a reactive sessionstorage from vueUse
let sessionOrder = useSessionStorage("basket", [] as SessionOrderType[]);
const calculateOverallTotalSum = (id: number, type: string, sum: number) => {
if (sessionOrder.value.some((p) => p.id === id && p.type.includes(type))) {
sessionOrder.value.map((p) => {
if (p.id === id && p.type === type) {
return (p.sum = sum);
}
});
} else {
let obj = {
id: id,
type: type,
sum: sum,
};
sessionOrder.value.push(obj);
}
summary.value = sessionOrder.value.reduce(
(total, item) => item.sum + total,
0
);
};
๐คFrallen
1๐
Some advice:
- If the value of the variable is not changing, declare it as a constant.
- As much as possible, declare event handler functions if you want to update reactive states based on DOM events. As your component grows in size, it can be tiring scrolling back-and-forth from the script tag to the template tag to check which DOM event updates the state/s. Furthermore, you can better handle complex computations with it.
- If a state is dependent on another state, and that state updates on DOM events, move them inside the event handler.
Child Component
<template>
<!-- Sample template -->
<div @click.prevent="calculateTotal('sub')">-</div>
<div @click.prevent="calculateTotal('add')">+</div>
</template>
<script setup>
import { ref } 'vue';
const props = defineProps(/** your props */);
const emit = defineEmits(["remove", "sum"]);
const count = ref(0);
const sum = ref(0);
/** Handler for the @click event */
const calculateTotal = (operation) => {
if (operation === 'add') {
count.value += 1;
} else if (operation === 'sub' && count.value > 0) {
count.value -= 1;
}
// You don't need to parseInt unless the value is not a number.
sum.value = count.value * props.item.attributes.Price;
emit('sum', { id: props.item.id, sum: sum.value });
};
</script>
Now, in your parent component, render your child components using v-for
. Then, declare a state that contains the overallTotalSum
of your basket. Finally, like the child component, create a handler that will grab the emitted basket item sum then do the necessary computation.
Parent Component
<template>
<BasketItem
v-for="item in items"
:key="item.id"
:item="item"
@sum="calculateOverallTotalSum"
/>
</template>
<script setup>
import { ref } 'vue';
import BasketItem from 'path';
const items = ref([/** your basket items */]);
const overallTotalSum = ref(0);
const calculateOverallTotalSum ({ id, sum }) => {
items.value = items.value.map(item => {
if (item.id === id) {
item.sum = sum;
}
return item
});
overallTotalSum.value = items.value.reduce(
(total, item) => item.sum + total, 0
);
};
</script>
Source:stackexchange.com