Создание бюджетного менеджера с помощью Vue.js и Node.js (Часть V)

Всех с Новым годом!

Приложение готово и развернуто.



Всем привет и добро пожаловать в последнюю часть этой серии руководств. Прошло почти два месяца с тех пор, как я опубликовал четвертую часть этой статьи. Поскольку я пытаюсь найти удаленную или заграничную работу, мне пришлось взять отпуск, чтобы сосредоточиться на своих исследованиях React и Redux, поэтому я прошу прощения за задержку.

Четвертая часть этой серии находится здесь.

Это последняя часть этой серии руководств, в которой мы узнаем, как создать полноценное приложение для управления бюджетом на Vue.js и Node.js.

Репозиторий GitHub для этого руководства находится здесь.

Также не забудьте прокомментировать любые сомнения, которые у вас возникли во время этого урока, или даже поправить меня в любом месте, где я мог что-то объяснить неправильно. И если вы знаете, как лучше справиться с любой частью этого урока, не стесняйтесь комментировать или связаться со мной!

Арсений Шютцер любезно перевел этот проект на Typescript, если кому-то интересно!

Https://github.com/senyaak/vue_express_manager_tutorial
https://github.com/senyaak/vue_express_manager_tutorial_frontend

Что мы будем делать сегодня

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

Улучшения API

Сначала перейдите в папку с нашими моделями и откройте наш budget.js файл:

Мы добавим в нашу модель поле описания:

Теперь перейдите в нашу папку app / api и откройте budget.js файл:

Мы исправим нашу функцию магазина, чтобы правильно сохранять наши новые бюджеты, добавим функцию индекса, чтобы мы могли получить один выбранный бюджет, добавим функцию редактирования для обновления наших бюджетов, добавим функцию удаления для удаления бюджетов и добавим функцию getByState для фильтрации наших бюджеты:

И наш client.js файл в нашей папке api сделаем то же самое:

И, наконец, давайте добавим новые маршруты, перейдите в нашу папку маршрутов и откройте budget.js:

И наш client.js:

Вот и все, что касается нашего API.

Улучшения нашего роутера

Затем мы добавим новые компоненты к нашим маршрутам, поэтому давайте откроем наш index.js файл в папке роутера:

Здесь мы импортировали и определили компонент с именем Create и назначили его как компонент для нашего домашнего маршрута (не беспокойтесь, мы создадим этот компонент через секунду).

Создание наших новых компонентов

Создать компонент

Начнем с компонента Create. Перейдите в папку с компонентами / страницами и создайте новый файл с именем Create.vue:

Первый названный слот budget-creation - это компонент, который мы будем использовать для создания новых бюджетов. Он будет виден, только если budgetCreation истинно, а editPage - ложно, мы передадим ему всех наших клиентов и метод с именем saveBudget.

Второй слот с именем client-creation - это компонент, используемый для создания новых клиентов. Он будет виден только тогда, когда budgetCreation - false и editPage - false, мы передадим ему только метод saveClient.

Третий названный слот budget-edit - это компонент, используемый для редактирования выбранного бюджета, он будет виден только в том случае, если budgetEdit и editPage верны. Мы передаем ему всех наших клиентов, выбранный бюджет и метод с именем fixClientNameAndUpdate.

И, наконец, наш последний названный слот используется для редактирования клиентов, он будет виден только тогда, когда budgetEdit ложно и editPage истинно, мы передаем ему выбранного клиента и метод с именем updateClient.

Компонент BudgetCreation

Давайте создадим наш компонент, используемый для создания новых бюджетов. Перейдите в папку с нашими компонентами и создайте новую папку с именем Creation, а внутри нее создайте компонент с именем BudgetCreation.vue.

Сначала я объясню шаблон компонента, так как это довольно большой компонент:

Шаблон

Сначала мы добавляем v-select, чтобы установить состояние бюджета, затем v-select, чтобы выбрать желаемого клиента. После этого у нас будет v-text-field для названия бюджета и v-text-field для описания.

Затем мы перебираем budget.items, чтобы мы могли добавлять и удалять элементы из статьи бюджета. У нас есть красная кнопка, которая вызывает removeItem функцию, передающую элемент, который мы хотим удалить.

После этого у нас есть три v-text-field для названия, цены и количества товара соответственно.

В конце строки у нас есть простой диапазон, в котором мы показываем subtotal для этого элемента (количество * цена).

Под нашими элементами у нас есть еще три элемента: синяя кнопка, которую мы используем для добавления дополнительных элементов, вызывающих функцию addItem, диапазон, в котором мы показываем общую стоимость этого бюджета (сумму промежуточных итогов каждого элемента), и зеленая кнопка, которую мы используем. чтобы сохранить бюджет в нашей базе данных, вызывая saveBudget и передавая бюджет, который мы хотим сохранить, в качестве параметра.

Скрипт

Теперь часть сценария:

Сначала мы получаем два реквизита, clients и saveBudget. Эти реквизиты взяты из нашего Home компонента.

Затем мы определим объект и массив как данные. Первый - budget. Этот объект используется для построения нашего бюджета, чтобы мы могли привязать к нему значения и сохранить его в нашей базе данных, у него есть заголовок, описание, состояние (запись по умолчанию), клиент, общая цена и предметы, каждый предмет имеет название, количество, цену и промежуточную сумму.

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

Под данными у нас есть несколько методов addItem и removeItem:

Каждый раз, когда мы нажимаем синюю кнопку, мы вызываем addItem, который, как следует из названия, добавляет элемент в наш items массив внутри нашего budget объекта.

removeItem делает обратное: каждый раз, когда нажимается красная кнопка, мы удаляем указанную статью из статей нашего бюджета.

Стиль

Компонент ClientCreation

Этот компонент представляет собой более простую, урезанную версию нашего компонента BudgetCreation:

Шаблон

Скрипт

Стиль

Компонент BudgetEdit

Этот компонент представляет собой модифицированную версию нашего компонента BudgetCreation:

Шаблон

Единственное различие между шаблонами BudgetEdit и BudgetCreation - это кнопка сохранения, текст которой мы меняем на «Обновить» и меняем метод на fixClientNameAndUpdate вместо использования saveBudget

Скрипт

Мы начинаем с получения трех реквизитов: clients, fixClientNameAndUpdate и selectedBudget. Данные идентичны данным BudgetCreation. У нас есть объект бюджета и массив состояний.

Затем у нас есть mounted жизненный цикл, в котором мы вызываем parseBudget - метод, который мы создадим через секунду.

И, наконец, у нас есть methods:

У нас будут те же две функции из BudgetCreation, addItem и removeItem, но у нас также будет новая, parseBudget:

Мы используем этот метод, чтобы установить объект бюджета этого компонента, равный нашему свойству selectedBudget, но все мы используем его, чтобы обновлять промежуточный итог и общую цену нашего объекта.

Стиль

Компонент ClientEdit

Подобно нашему последнему компоненту, он будет выглядеть так же, как наш ClientCreation, за исключением того, что он будет использовать другой метод, вместо saveClient мы будем использовать updateClient

Шаблон

Скрипт

Стиль

Это все, что касается новых компонентов.

Улучшение наших компонентов

Теперь нам просто нужно внести несколько улучшений в наши существующие компоненты, и все готово.

Начнем с нашего ListBody компонента:

Шаблон

Нам нужно внести пару исправлений и дополнений в этот компонент, сначала мы добавим новое условие в наши md-list-item v-if

parsedBudgets === null

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

Мы добавляем метод getItemAndEdit к нашей (сейчас) первой кнопке и deleteItem к нашей последней кнопке, передавая элемент, данные и переменную budgetsVisible в качестве параметров.

Ниже у нас есть еще один блок md-item-list, который мы используем для отображения отфильтрованных бюджетов на основе результатов поиска.

Скрипт

В этом компоненте мы получаем много реквизита:

  • данные: либо бюджеты, либо клиенты, но не то и другое вместе
  • budgetsVisible: чтобы проверить, видим ли мы бюджеты или клиентов, верно или неверно
  • deleteItem: функция, которая принимает элемент в качестве параметра
  • getBudget: функция, которую мы используем для получения единого бюджета, чтобы мы могли его редактировать
  • getClient: функция, которую мы используем для получения одного клиента, чтобы мы могли его редактировать
  • parsedBudgets: бюджеты, которые мы отфильтровали с помощью поиска.

У нас есть только один метод для этого компонента, getItemAndEdit, он принимает элемент в качестве параметра, и если элемент имеет свойство phone, мы решаем, клиент это или бюджет.

Стиль

Теперь давайте улучшим наш Header компонент:

Шаблон

Во-первых, мы меняем v-model нашего ввода для поиска на searchValue.

Мы также модифицируем наш v-select, чтобы привязать метод selectState к его change событию.

Скрипт

Мы добавили два новых свойства: selectState - функция, а search - строка.

Мы изменили search наших данных на searchValue и сделали statusItem элементы массива в нижнем регистре.

Стиль

И, наконец, мы изменим наш Home компонент:

Шаблон

Это был наиболее измененный компонент, теперь мы передаем budgetsVisible, selectState, search и toggleVisibleData в качестве свойств, мы также переключаем другую переменную в toggleVisibleData и добавляем v-model к search.

в нашем теге list мы добавляем v-if, чтобы он отображался только тогда, когда мы находимся на странице списка, мы добавили много новых свойств в наш list-body.

мы добавили тег create, который действует аналогично list, но мы отображаем его только тогда, когда находимся на странице создания, мы передаем ему все данные клиента и бюджета, а также все методы получения и обновления.

Мы добавили две новые кнопки в наш v-fab-transition, чтобы мы могли перечислять бюджеты, клиентов и создавать бюджеты и клиентов.

Скрипт

Мы добавили много новых данных в этот компонент

  • parsedBudgets: мы используем это как массив для хранения всех бюджетов, отфильтрованных нашим поиском
  • бюджет: выбранный бюджет, чтобы мы могли его изменить
  • клиент: выбранный клиент, чтобы мы могли его редактировать
  • состояние: выбранное состояние, поэтому мы можем отображать только бюджет с этим состоянием
  • поиск: наш фильтр поиска, используемый при вводе поиска
  • бюджеты: все бюджеты, полученные из нашего API.
  • клиенты: все клиенты, полученные из нашего API.
  • budgetHeaders: массив, используемый для отображения текстов заголовков нашей таблицы
  • clientHeaders: массив, используемый для отображения текстов заголовков нашей таблицы
  • budgetsVisible: используется для определения, указываем ли мы бюджеты или клиентов
  • закусочная: используется для отображения нашей закусочной
  • тайм-аут: тайм-аут закусочной
  • message: сообщение закусочной
  • fab: состояние нашего FAB, по умолчанию false
  • listPage: используется для проверки, находимся ли мы на странице со списком, по умолчанию - true
  • createPage: используется для проверки, находимся ли мы на странице создания, по умолчанию - false
  • editPage: используется для проверки, находимся ли мы на странице редактирования, по умолчанию - false
  • budgetCreation: используется для проверки, создаем ли мы бюджет или клиента, по умолчанию - true
  • budgetEdit: используется для проверки, редактируем ли мы бюджет или клиента, по умолчанию - true
  • snackColor: цвет нашей закусочной

Наш установленный жизненный цикл для этого компонента одинаков, мы выбираем для всех бюджетов и клиентов.

Мы добавили функцию watch к нашему поисковому вводу благодаря @mrmonkeytech для простого решения с регулярными выражениями (я переоценил его).

Мы улучшили все наши методы и добавили много новых:

getAllBudgets мы добавили новые параметры в наш анализатор данных, и теперь мы вызываем errorHandler в нашем catch блоке.

То же и для нашего getAllClients

мы добавили getBudget и getClient, которые отвечают за выборку только выбранного элемента из нашего API.

enableEdit принимает строку в качестве параметра, отправляя нас на страницу редактирования соответствующего элемента.

saveBudget и saveClient используются для сохранения нашего товара в нашей базе данных

fixClientNameAndUpdate используется для установки правильного имени для нашего клиента на основе его идентификатора и для обновления бюджета в нашей базе данных, вызывая updateBudget

updateBudget используется для обновления нашего бюджета в нашей базе данных

updateClient используется для обновления нашего клиента в нашей базе данных

deleteItem - это общая функция, используемая для удаления элемента из нашей базы данных, она принимает параметр selected (который является выбранным элементом), параметр items (который является либо бюджетом, либо клиентами) и параметр api, который представляет собой строку

errorHandler - наш метод обработки ошибок

removeItem используется в deleteItem для удаления элемента из нашего приложения после его удаления из базы данных.

dataParser все тот же, мы его не меняли

resetFields используется для сброса всех элементов по умолчанию после создания нового элемента, поэтому клиент может добавить столько бюджетов или клиентов, сколько он хочет, без необходимости удалять каждое поле после каждого сохранения.

selectState используется для выбора правильного состояния из v-select нашего заголовка и фильтрации нашего списка на его основе.

getBudgetsByState используется в selectState для получения только бюджетов с выбранным состоянием

Стиль

Что дальше

Мы, наконец, закончили эту серию руководств, я намерен написать больше руководств, так как я учусь на них не меньше, чем вы. Я начну писать уроки React + Redux, а также уроки Phaser для разработки игр.

Если вы хотите получить от меня другие руководства и статьи, не забудьте подписаться на меня здесь, на medium или github.

Это была отличная возможность для меня научиться и попытаться научить вас тому, что я могу, если вы думаете, что я мог бы сделать что-то по-другому, не стесняйтесь написать мне здесь или по электронной почте!

Всем спасибо за все!