Создание бюджетного менеджера с помощью 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.
Это была отличная возможность для меня научиться и попытаться научить вас тому, что я могу, если вы думаете, что я мог бы сделать что-то по-другому, не стесняйтесь написать мне здесь или по электронной почте!
Всем спасибо за все!