Найти в Дзене
DEVHOUSE ACADEMY

КАК СДЕЛАТЬ КОМПОНЕНТ ДЛЯ КАЛЬКУЛЯТОРА РАСЧЕТА СТОИМОСТИ

В этом посте я расскажу, как сделать компонент для калькулятора расчета стоимости. Постановка задачи такая: ✔️ В калькулятор необходимо добавлять неограниченное количество комнат и указывать их длину и ширину (предполагается, что они прямоугольные). ✔️ Калькулятор должен моментально вычислять стоимость ремонта, исходя из оценки: 50 тыс. рублей на 1 кв. метр. В качестве фремворка будем использовать VueJS 3 версии. Сначала создадим демонстрационный проект для тестирования нашего компонента. Для этого нужно будет установить среду для сборки NodeJS c официального сайта: https://nodejs.org/ru Также будем использовать IDE VSCode, ее тоже можно скачать бесплатно с официального сайта: https://code.visualstudio.com Создаем новую папку для проектов открываем ее в vscode и запускаем в нем терминал. Все эти шаги описаны подробно в нашей предыдущей статье: 1 ЭТАП В терминале вбиваем команду для создания нового проекта vuejs (попутно он предложит установить утилиту vue-create, а потом пр
Оглавление

В этом посте я расскажу, как сделать компонент для калькулятора расчета стоимости.

Постановка задачи такая:

✔️ В калькулятор необходимо добавлять неограниченное количество комнат и указывать их длину и ширину (предполагается, что они прямоугольные).

✔️ Калькулятор должен моментально вычислять стоимость ремонта, исходя из оценки: 50 тыс. рублей на 1 кв. метр.

В качестве фремворка будем использовать VueJS 3 версии.

Сначала создадим демонстрационный проект для тестирования нашего компонента.

Для этого нужно будет установить среду для сборки NodeJS c официального сайта: https://nodejs.org/ru

Также будем использовать IDE VSCode, ее тоже можно скачать бесплатно с официального сайта: https://code.visualstudio.com

Создаем новую папку для проектов открываем ее в vscode и запускаем в нем терминал.

Все эти шаги описаны подробно в нашей предыдущей статье:

ДЕЛАЕМ ТАЙМЕР ПОШАГОВО НА ФРЕМВОРКЕ VueJS
DEVHOUSE ACADEMY26 октября 2023

1 ЭТАП

В терминале вбиваем команду для создания нового проекта vuejs (попутно он предложит установить утилиту vue-create, а потом предложит указать название проекта и другие опции - там пока можно везде выбрать No):

```sh

npm create vue@latest

```

Переходим в терминале в папку проекта:

```sh

cd название проекта

```

Устанавливаем локально зависимости:

```sh

npm i

```

Далее для локального запуска проекта нужно будет вбить в терминал:

```sh

npm run dev

```

Запустится локальный стенд и будет указана ссылка, по которой можно посмотреть результат в браузере.

Первым делом создадим компонент Calc.vue в папке /src/components/ со следующим содержимым:

```js

// Calc.vue

<script setup>

</script>

<template>

    <input type="button" value="+ Добавить комнату">

    <table>

        <tr>

            <th>Комната:</th>

            <th><input type="text"></th>

        </tr>

        <tr>

            <td>Длина</td>

            <td><input type="number"> м.</td>

        </tr>

        <tr>

            <td>Ширина</td>

            <td><input type="number"> м.</td>

        </tr>

        <tr>

            <td></td>

            <td><input type="button" value="удалить комнату"></td>

        </tr>

    </table>

    <div>

        Итог: 100 000 руб

    </div>

</template>

```

Это будет прототип будущего калькулятора.

Добавим копонент в главный файл App.vue:

```js

// App.vue

<script setup lang="ts">

import Calc from './components/Calc.vue'

</script>

<template>

  <main>

    <Calc />

  </main>

</template>

```

Теперь в браузере это будет выглядеть вот так:

ЭТАП 2 

Теперь реализуем функционал добавления комнат:

```js

// Calc.vue

<script setup>

import { ref, computed } from "vue"

// пустой объект с параметрами комнаты

const emptyRoom = {

    title: "",

    length: 0,

    width: 0,

}

// массив комнат, заполненный одной

const rooms = ref([

    {...emptyRoom} // spread оператор используется для копирования полей объекта

])

// функция добавления новой комнаты в массив

const newRoom = () => {

    rooms.value.push({

        ...emptyRoom

    })

}

// функция удаления комнаты по индексу

const removeRoom = (index) => {

    rooms.value.splice(index, 1)

}

</script>

...

```

Теперь свяжем верстку с данными в массиве.

Для этого используем цикл и будем связыть поля каждого объекта комнаты с полями ввода через v-model:

```js

// Calc.vue

...

<table>

    <input

        type="button"

        value="+ Добавить комнату"

    >

    <template v-for="room, index in rooms">

        <tr>

            <th>Комната:</th>

            <th><input type="text" v-model="room.title"></th>

        </tr>

        <tr>

            <td>Длина</td>

            <td><input type="number" v-model="room.length"></td>

        </tr>

        <tr>

            <td>Ширина</td>

            <td><input type="number" v-model="room.width"></td>

        </tr>

        <tr>

            <td></td>

            <td>

                <input

                    type="button"

                    value="удалить комнату"

                >

            </td>

        </tr>

    </template>

</table>

...

```

Теперь добавим обработчики нажатий на кнопки:

```js

// Calc.vue

...

<input

    type="button"

    value="+ Добавить комнату"

    @click="newRoom"

>

...

<input

    type="button"

    value="удалить комнату"

    @click="removeRoom(index)"

>

...

```

Теперь мы можем добавлять и удалять комнаты, а также изменять параметры каждой:

-2

ЭТАП 3

Реализуем логигу расчета стоимости в режиме реального времени.

В верстку на место "Итога" добавим вывод переменной resultPrice:

```js

// Calc.vue

...

<div>

    Итог: {{ resultPrice }} руб

</div>

...

```

В секции script теперь объявим эту переменную как  вычисляемое свойство

resultPrice:

```js

// Calc.vue

<script setup>

...

const PRICE_PER_METR2 = 50000 // стоимость кв метра

const resultPrice = computed(() => {

    // расчет стоимости: для каждой комнаты перемножаем длину на ширину и на стоимость кв метра

    let result = rooms.value.reduce((acc, room) => {

        return acc += room.length * room.width * PRICE_PER_METR2

    }, 0)

    // результат преобразуем в строку, чтобы обеспечить локазиванный формат вывода числа (с отделением разрядов пробелами)

    return result.toLocaleString()

})

...

```

В итоге получаем рабочий компонент:

-3

Итоговый код копонента должен получится такой:

```js

// Calc.vue

<script setup>

import { ref, computed } from "vue"

// массив комнат

const emptyRoom = {

    title: "",

    length: 0,

    width: 0,

}

const rooms = ref([

    {...emptyRoom}

])

const newRoom = () => {

    rooms.value.push({

        ...emptyRoom

    })

}

const removeRoom = (index) => {

    rooms.value.splice(index, 1)

}

// расчет

const PRICE_PER_METR2 = 50000

const resultPrice = computed(() => {

    let result = rooms.value.reduce((acc, room) => {

        return acc += room.length * room.width * PRICE_PER_METR2

    }, 0)

    return result.toLocaleString()

})

</script>

<template>

    <input

        type="button"

        value="+ Добавить комнату"

        @click="newRoom"

    >

    <table>

        <template v-for="room, index in rooms">

            <tr>

                <th>Комната:</th>

                <th><input type="text" v-model="room.title"></th>

            </tr>

            <tr>

                <td>Длина</td>

                <td><input type="number" v-model="room.length"> м.</td>

            </tr>

            <tr>

                <td>Ширина</td>

                <td><input type="number" v-model="room.width"> м.</td>

            </tr>

            <tr>

                <td></td>

                <td>

                    <input

                        type="button"

                        value="удалить комнату"

                        @click="removeRoom(index)"

                    >

                </td>

            </tr>

        </template>

    </table>

    <div>

        Итог: {{ resultPrice }} руб

    </div>

</template>

```