Веб-приложение на Node и Vue, часть 2: компоненты, формы, маршруты

Веб-приложение на Node и Vue, часть 2: компоненты, формы, маршруты

Перед вами — вторая часть серии материалов, которая посвящена созданию веб-приложения Budget Manager с использованием Node.js, Vue.js и MongoDB. В первой части мы занимались сервером, а именно — подготовили основные методы RESTful API и наладили JWT-аутентификацию. Сегодня приступим к работе над клиентской частью приложения, создадим каркас фронтенда, средства для регистрации в системе и входа в неё, поговорим о маршрутах и об их защите.

Установка Vue.js и использование vue-cli

Установить Vue.js довольно просто. Мы планируем использовать vue-cli с шаблоном webpack . Обратившись к руководству по Vue, можно выяснить, что для установки vue-cli и подготовки рабочей среды используются такие команды:

Продолжим работу над проектом, создав папку application в его корневой директории. Этот шаг можно и пропустить, создав папку в процессе работы с vue-cli . Если вы решите не создавать папку, тогда вам нужно дать проекту имя, выполнив команду такого вида:

Вот как выглядит проект после создания папки application :

Теперь перейдём в только что созданную папку с помощью интерпретатора командной строки, и, если vue-cli ещё не установлен, выполним следующую команду:

Эта команда позволяет установить vue-cli глобально, поэтому неважно, в какой именно папке мы будем находиться, выполнив её.

Теперь вызовем следующую команду:

Обратите внимание на то, что тут не указано имя проекта, так как подразумевается, что команда выполняется в папке application , уже созданной для размещения в ней приложения.

После выполнения вышеприведённой команды и загрузки шаблона вам будет задан ряд вопросов:

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

Далее, всё ещё оставаясь в папке application , устанавливаем зависимости и запускаем проект.

Теперь можно полюбоваться на стандартную страницу Vue.

Очистка приложения Vue

Уберём из приложения некоторые ненужные нам стандартные элементы. Для этого надо перейти в папку application/src/assets и удалить logo.png , так как этим файлом мы пользоваться не будем. Далее, откроем файл корневого компонента App.vue из папки application/src и приведём его к виду, представленному следующим фрагментом кода:

Теперь надо очистить маршруты. Для этого откроем файл index.js в папке router и приведём его к такому виду:

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

Теперь, на последнем этапе очистки стандартного приложения, удалим файл HelloWorld.vue из папки components .

Установка зависимостей

Прежде чем заняться разработкой фронтенда приложения, нужно установить ещё несколько зависимостей. Перед выполнением следующей команды проверьте, находитесь ли вы в папке application :

Теперь установим зависимости разработки:

Мы будем использовать axios для обработки HTTP-запросов. В vuetify нас интересуют визуальные компоненты и возможность пользоваться компоновкой элементов на основе сетки. Библиотеку vue-cookie будем применять для работы с куки-файлами. Пакеты sass-loader и node-sass позволят нам пользоваться SCSS.

Начало работы над фронтендом приложения

Теперь, когда все подготовительные мероприятия завершены, займёмся разработкой. Перейдём к папке components и создадим в ней папку pages , в которой создадим папку Authentication . В этой папке надо создать файл Authentication.vue , представляющий компонент, которым будем пользоваться для аутентификации. Вот что должно в итоге получиться:

В файле Authentication.vue разместим следующий код:

Расширением этого компонента займёмся позже, а пока перейдём в папку router и поработаем с маршрутами.

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

После этого, если перейти по адресу http://localhost:8080/#/login, можно увидеть пустую страницу с надписью «Auth!». Это говорит о том, что маршрут аутентификации работает. Теперь откроем файл main.js из папки src и импортируем vuetify и vue-cookie :

Перейдём к компоненту App.vue из папки src и займёмся стилями. Сначала нужно подготовить тег style . Разместим его сразу после закрытия тега script :

Теперь переходим в папку src/assets и создаём в ней файл styles.scss и папку partials . В этой папке создадим два частичных шаблона, представленных файлами _variables.scss и _animations.scss . В результате должна получиться такая структура:

В файле _variables.scss зададим такие параметры:

В файл _animations.css добавим описания анимаций bounceIn и slideInFromLeft :

Импортируем частичные шаблоны в styles.scss :

Теперь, в папке assets , создадим папку images . Сюда можно поместить любое изображение, которое будет использоваться в качестве фона. Здесь, в репозитории, можно найти изображение, которое применяется в этом материале.

Настроим внешний вид приложения, приведя к следующему виду блок стилизации в файле App.vue :

Тут мы импортируем ранее подготовленные стили scss и задаём использование фиксированного фонового изображения для приложения. Мы стремимся к тому, чтобы на любом устройстве экран приложения выглядел примерно одинаково.

В псевдоэлементе body :after мы задаём параметр background-color , записывая в него значение переменной $background-tint . Это позволит применить к фоновому изображению пурпурный цветной фильтр. Вот как выглядят разные варианты фонового изображения.

Обратите внимание на то, что всё, что касается стилизации и работы с фоном, на функционал приложения не влияет, поэтому вы вполне можете пропустить эти шаги или украсить приложение так, как вам захочется.

Масштабирование области просмотра и загрузка иконок

Благодаря этому шагу мы обеспечим правильное отображение приложения на мобильных устройствах. Кроме того, на данном этапе работы мы загрузим иконки в стиле Material Design. Для того, чтобы всё это сделать, перейдём к файлу index.html , который расположен в папке application и добавим следующее в тег head :

Разработка компонента Authentication

Теперь, когда мы немного украсили приложение, избавившись, по крайней мере, от скучных белых страниц, продолжим работу над компонентом Authentication . Создадим в папке Authentication файл index.js .

Импортируем в него то, что нам понадобится и объявим константу, в которую запишем путь к API:

Теперь создадим объект Authentication , который будет содержать нужные нам методы:

Мы начинаем работу над этим компонентом, объявляя объект с именем user , который хранит сведения о том, аутентифицирован ли пользователь.

Теперь напишем методы:

В первом методе используются три аргумента:

  • context : это — компонент Vue.
  • credentials : тут будут имя пользователя ( username ) и пароль ( password ).
  • redirect : здесь будет путь, по которому мы собираемся перенаправить пользователя.

В противном случае мы устанавливаем поле snackbar объекта context в true и записываем в message сообщение об ошибке.

Второй метод очень похож на первый, его мы используем для создания новой учётной записи. Разница между ним и первым методом заключается в конечной точке, с которой мы работаем. Третий метод используется для проверки того, аутентифицирован пользователь или нет. Последний метод позволяет возвратить заголовок Authorization .

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

Здесь имеется элемент div с классом l-auth-container , который выполняет роль контейнера. Следом идёт ещё один div с классом l-auth , который содержит структуру элементов для организации формы ввода, в частности, это элемент v-form , привязанный к данным переменной validLogin .

Внутри него находится пара подписанных полей ввода v-text-field , которые привязаны к данным из credentials (мы займёмся этими данными ниже). Поля снабжены иконками, взятыми из https://material.io/icons/, с ними также связаны правила по проверке ввода (и там и там — одни и те же правила, не будем усложнять проект), кроме того, оба эти поля являются обязательными.

Второе поле ввода предназначено для пароля, оно снабжено иконкой, которая указывает на то, может ли пользователь видеть вводимый пароль. У этой иконки есть коллбэк, являющийся стрелочной функцией, который позволяет переключать значение переменной loginPasswordVisible с true на false и наоборот. Если эта переменная установлена в true , то параметр type поля ввода устанавливается в text , иначе это password .

И, наконец, тут присутствуют описания кнопок, которые мы используем для создания новой учётной записи или для отправки формы с целью входа в систему.

Следующий фрагмент кода описывает структуру формы регистрации в системе, которая видна лишь в том случае, если переменная signUpVisible установлена в true . Устройство этой формы похоже на устройство формы входа в систему, тут изменены лишь несколько строк. В частности, здесь используется переменная signUpPasswordVisible вместо loginPasswordVisible и другой метод обработки щелчка по кнопке.

Далее, тут имеется панель v-snackbar , которая, в ходе аутентификации, используется для вывода сообщений.

Теперь, в том же файле Authentication.vue , опишем скрипт компонента:

Тут всё начинается с импорта файла index.js из папки Authentication , так как нам нужен метод authenticate , определённый внутри этого файла.

Взглянем теперь на переменные, хранящие данные компонента:

  • snackbar : используется для панели сообщений.
  • validLogin : используется для проверки формы входа в систему.
  • validSignUp : используется для проверки формы регистрации.
  • signUpVisible : используется для вывода формы регистрации (при установке в true ).
  • loginPasswordVisible : указывает на то, может ли пользователь видеть пароль, вводимый в форме входа в систему.
  • signUpPasswordVisible : указывает на то, можно ли видеть пароль, вводимый в форме регистрации.
  • rules : правила проверки данных, введённых в поля форм.
  • credentials : объект, привязанный к полям ввода формы входа в систему, используемый для аутентификации пользователя.
  • newUser : объект, привязанный к полям ввода формы регистрации в системе.
  • message : используется для вывода сообщений в ходе аутентификации.

И, наконец, вот код стилизации компонента, который надо разместить в том же файле Authentication.vue (тут вы можете дать волю фантазии и сделать всё таким, как вам хочется):

Вот как выглядят компоненты для входа в систему и регистрации нового пользователя.

Разработка компонента Home

Перейдём в папку pages и создадим файл компонента Home.vue :

На данный момент в шаблоне этого компонента, код которого представлен ниже, будут лишь несколько текстовых сообщений:

Этот компонент является основой для домашней страницы, которой мы займёмся в следующей части этой серии. А пока выполним GET-запрос к API для получения всех зарегистрированных пользователей, используя отладочный метод API и передавая токен в заголовке запроса. Вот как это будет выглядеть:

Защита системы навигации

Откроем файл index.js из папки router . Вот к какому виду его нужно привести:

Рассмотрим этот код.

В этой строке мы импортируем файл Authentication , называя его Auth , так как компонент Authentication также был импортирован.

Тут мы даём имя объекту Router для того, чтобы позже создать защиту системы навигации. Также мы добавляем путь к компоненту Home . В параметре meta.requiredAuth будет записано true . Это означает, что если к этому компоненту попытается получить доступ неаутентифицированный пользователь, он будет перенаправлен на страницу входа в систему.

Здесь мы защищаем систему навигации. А именно, регистрируем глобальный сторожевой хук, пользуясь которым перед переходом по каждому маршруту проверяем, установлен ли его параметр meta.requiredAuth в true . Если это так, мы проверяем объект пользователя из Authentication . Если пользователь не аутентифицирован, мы перенаправляем его на страницу входа в систему.

Этой командой экспортируем маршрутизатор.

Теперь откройте файл main.js в папке application . Тут мы собираемся импортировать файл Authentication и вызвать метод checkAuthentication :

Без этого, если пользователь перезагрузит страницу или закроет её, а потом снова откроет, он будет перенаправлен на страницу входа в систему.

📎📎📎📎📎📎📎📎📎📎