Калькулятор теплиц
делаю калькулятор для расчёта стоимости теплицы в зависимости от выбранных параметров и столкнулся с проблемой, а именно каким образом должен выглядеть массив и как его правильно обработать, в условии сказано, что длина, шаг и стоимость взаимосвязаны.
Например:
1/1.2 - цена
1/1.3 - цена
2/1.2 - цена
2/1.3 - цена
Пробовал обработать на фронте используя следующие виды массивов:
1.
array:6 [
0 => [
0 => "1"
1 => "1.1"
2 => "1111"
]
1 => [
0 => "1"
1 => "2"
2 => "11111"
]
2 => [
0 => "3"
1 => "1.1"
2 => "3333"
]
3 => [
0 => "3"
1 => "2"
2 => "33333"
]
4 => [
0 => "4"
1 => "1.1"
2 => "4444"
]
5 => [
0 => "4"
1 => "2"
2 => "44444"
]
]
array:3 [▼
1 => [
0 => [
"1.1" => "1111"
]
1 => [
2 => "11111"
]
]
3 => [
0 => [
"1.1" => "3333"
]
1 => [
2 => "33333"
]
]
4 => [
0 => [
"1.1" => "4444"
]
1 => [
2 => "44444"
]
]
]
Столкнулся с проблемами, а именно в 1-ом варианте - это дубли, а во 2-ом в качестве индекса я использовал длину, но при выводе через v-for не могу корректно вывести шаг и стоимость без дублей, ещё задача усложняется тем, что 1-ые параметры должны быть активными по умолчанию.
P.S. Компонент, который я пытался реализовать прикрепил
</script>
<template>
<div>
<div
v-for="(product, i) in data.products"
:key="i"
class="product__lists"
>
<div class="row">
<div class="col-lg-6">
<img
:src="setImage(product)"
class="img-fluid"
:alt="product.name"
>
</div>
<div class="col-lg-6">
<p class="title">{{ product.name }}</p>
<div
v-if="product['full_description'] != null"
class="text"
v-html="product['full_description']"
>
</div>
<div
v-if="product.options != null"
class="calculator"
>
<p class="sub__title">Калькулятор</p>
<div class="parameters">
<p>Выберите длину теплицы:</p>
<button
v-for="(option, index) in data.options"
v-if="option.product == product.id"
type="button"
class="btn btn__select"
:class="{ 'active' : form.options.some(items => items === option) }"
@click = "getOptions(option, product)"
v-model="option.length"
>{{ option.length }}</button>
</div>
<div class="parameters">
<p>Выберите шаг между дугами:</p>
<button
v-for="(option, index) in data.options"
v-if="option.product == product.id"
type="button"
class="btn btn__select"
:class="{ 'active' : form.options.some(items => items === option) }"
@click = "getOptions(option, product)"
v-model = "option.steps"
>{{ option.steps }}</button>
</div>
<div
v-if="product.equipments.length > 0"
class="parameters"
>
<p>Дополнительное оборудование:</p>
<button
v-for="(equipment, index) in product.equipments"
:key="index"
type="button"
class="btn btn__select"
:class="{ 'active' : form.equipments.some(items => items.id === equipment.id)}"
@click = "getEquipment(equipment, product)"
>{{ equipment.name }}</button>
</div>
</div>
<div class="row">
<div class="col-md-6 col-lg-6 d-flex align-items-center">
<div class="price">
Цена: <span>{{ priceFloat(product.total) }}</span> руб
</div>
</div>
<div class="col-md-6 col-lg-6 d-flex align-items-center">
<button
type="button"
class="btn btn__order"
@click = "openModal(product)"
>Заказать</button>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import axios from 'axios';
import ContactFormPhone from './ContactFormPhoneComponent.vue';
export default {
name: "ProductComponent",
components: {
ContactFormPhone
},
data() {
return {
data: {
products: [],
options: [],
},
form: {
options: [],
equipments: [],
total: null,
modal: {
show: false,
product: null,
}
}
}
},
created() {
let self = this,
array = [];
axios.post('/products', {})
.then(function (response) {
self.data.products = response.data.products;
let index = 0;
self.data.products.forEach((product, i) => {
if(product.options != undefined) {
product.options.forEach((item, i) => {
array[index] = {
product: product.id,
length: parseFloat(item[0]),
steps: parseFloat(item[1]),
price: parseFloat(item[2])
};
if(i == 0) {
self.form.options.push(array[index]);
product.total = parseFloat(item[2]);
}
index++;
});
}
});
array.sort(function (a, b) {
return a.length - b.length || a.steps - b.steps;
});
self.data.options = array;
//console.log(response);
})
.catch(function (error) {
console.log(error);
});
},
methods: {
//Проверям картинку
setImage(item) {
let path = '/storage/product_images/';
if(item.image == null) {
return '/images/no-image.png';
}
return path + item.image;
},
//Прибавляем стоимость в зависмости от выбора параметра
getOptions(item, product) {
if (item.product == product.id) {
console.log(123);
this.form.options.splice(item, 1);
}
this.form.options.push(item);
if(product.total == undefined || product.total == null) {
product.total = 0;
}
product.total += parseFloat(item.price);
//console.log(item);
},
//Записываем выбранные значения в массив
getEquipment(item, product) {
let index = this.form.equipments.indexOf(item);
if (index > -1) {
let items = this.form.equipments[index];
product.total -= parseFloat(items.price);
return this.form.equipments.splice(index, 1);
}
this.form.equipments.push(item);
if(product.total == undefined || product.total == null) {
product.total = 0;
}
product.total += parseFloat(item.price);
},
priceFloat(price) {
if(price == undefined || price == null) {
return price = 0;
}
return parseFloat(price).toFixed(2);
},
openModal(product) {
this.form.modal.show = true;
this.form.modal.product = product;
}
},
}
</script>