Нам все еще не хватает компонентов создания и обновленияд данных, и в этой статье мы собираемся реализовать эти недостающие части.
Создание объекта-владельца (Owner)
Мы собираемся создать форму с тремя полями ввода: имя, дата рождения и адрес. Как только пользователь заполнит данные и отправит форму, мы отправим на сервер POST
запрос. После получения ответа появится модальное окно и отобразится, успешно ли мы создали сущность «Владелец».
Чтобы упростить чтение и понимание, мы собираемся написать этот компонент в нескольких сегментах. Начнем с шаблона.
Шаблон OwnerCreate
Во-первых, мы собираемся создать форму с тремя полями ввода. Для этого давайте создадим компонент OwnerCreate.vue
в папке src/components/Owner
:
<template>
<b-container fluid>
<div class="form-wrapper">
<b-form @submit.prevent="createOwner">
<b-form-group
:label-cols="2"
breakpoint="md"
horizontal
label="Name of the owner:"
for="name">
<b-col :md="5">
<b-input
id="name"
v-model="formData.name"
maxlength="60"
required />
</b-col>
</b-form-group>
<b-form-group
:label-cols="2"
breakpoint="md"
horizontal
label="Date of birth:"
for="dateOfBirth">
<b-col :md="5">
<b-input
id="dateOfBirth"
v-model="formData.dateOfBirth"
type="date"
required />
</b-col>
</b-form-group>
<b-form-group
:label-cols="2"
breakpoint="md"
horizontal
label="Address:"
for="Address">
<b-col :md="5">
<b-input
id="Address"
v-model="formData.address"
maxlength="100"
required />
</b-col>
</b-form-group>
</b-form>
</div>
</b-container>
</template>
В этом шаблоне есть кое что новое. В теге формы есть оператор @submit.prevent
. Ранее мы узнали, что @submit
- это синтаксис для прослушивания события submit
. Но теперь у нас есть модификатор prevent
, который эквивалентен стандартному выражению JavaScript event.preventDefault()
. Таким образом, мы предотвращаем перенаправление на действие формы в собственном браузере, потому что мы хотим отправлять данные с помощью Axios.
Также обратите внимание на конструкцию v-model
. Чуть позже мы вернемся к ней.
Под тегом формы мы собираемся создать кнопки Сохранить
и Отменить
. Первая отправит форму, а вторая перенаправит на маршрут OwnerList
.
Итак, прямо под последним тегом b-form-group
мы вставим этот фрагмент кода:
<template>
<b-container fluid>
<div class="form-wrapper">
<b-form @submit.prevent="updateOwner">
<b-form-group
:label-cols="2"
breakpoint="md"
...
</template>
Кроме того, мы собираемся создать модальное окно, чтобы показать информацию, было ли наше действие успешным. Мы собираемся поместить это модальное окно перед закрывающим тегом b-container
:
<b-modal
ref="alertModal"
:title="alertModalTitle"
:ok-only="true"
@ok="onAlertModalOkClick">
<p class="my-4">{{ alertModalContent }}</p>
</b-modal>
В продолжение добавим несколько стилей:
<style>
.form-wrapper {
margin-top: 20px;
min-height: 20px;
padding: 19px;
margin-bottom: 20px;
background-color: #f5f5f5;
border: 1px solid #e3e3e3;
border-radius: 4px;
box-shadow: inset 0 1px 1px rgba(0,0,0,.05);
}
</style>
Далее мы реализуем логику этого шаблона.
Сценарий OwnerCreate
Нам нужно создать переменные, которые будут хранить данные из наших инпутов. Нам нужно еще создать переменные для заголовка и содержимого модального окна. Для этого мы собираемся создать переменную isSuccessfully
, чтобы отображать правильное сообщение о том, был ли наш запрос POST
успешным или нет.
Пришло время объяснить директиву v-model
и то, как мы используем ее для связывания этих переменных с входными данными.
Это похоже на выражение привязки данных (:prop="value"
), которое вы могли видеть в предыдущих частях, но это привязка через v-model
является двусторонней. В предыдущих частях мы только передали данные из родительского компонента в дочерний компонент с использованием синтаксиса :prop="value"
, и если дочерний компонент попытается изменить это значение, появится предупреждение. потому что это запрещено. С помощью директивы v-model
родительский и дочерний компоненты могут изменять это значение, и оба компонента будут уведомлены об этом изменении.
<script>
export default {
name: 'OwnerCreate',
data() {
return {
formData: {
name: '',
dateOfBirth: '',
address: ''
},
alertModalTitle: '',
alertModalContent: '',
isSuccessfully: false
};
},
};
</script>
Теперь давайте реализуем метод createOwner
который отправляет запрос POST и объект formData
на сервер. В зависимости от ответа сервера переменной isSuccessfully
будет установлено значение true или false. Если действие выполнено успешно, появится модальное окно и объект formData
будет очищен. Если возникнет какая-либо проблема, модальное окно отобразит сообщение об ошибке.
Давайте реализуем этот метод:
methods: {
createOwner() {
OwnerService.create(this.formData)
.then(() => {
this.isSuccessfully = true;
this.alertModalTitle = 'Successfully';
this.alertModalContent = 'Successfully created Account Owner';
this.$refs.alertModal.show();
this.formData = {
name: '',
dateOfBirth: '',
address: ''
};
})
.catch((error) => {
this.isSuccessfully = false;
this.alertModalTitle = 'Error';
this.alertModalContent = error.response.data;
this.$refs.alertModal.show();
});
}
}
Нам также необходимо импортировать ссылку OwnerService
:
import OwnerService from '@/api-services/owner.service';
Когда появится модальное окно, нам нужно нажать кнопку OK
. Этот действие вызовет метод onAlertModalOkClick
, который перенаправит пользователя на маршрут OwnerList
, если ответ будет успешным успешным.
Мы собираемся отредактировать компонент OwnerCreate.vue
еще раз, чтобы реализовать этот метод:
onAlertModalOkClick() {
if (this.isSuccessfully) {
this.$router.push({ name: 'OwnerList' });
}
}
Нам все еще нужно проложить маршрут и путь к этому компоненту.
Переход к компоненту OwnerCreate
Давайте отредактируем файл src/router/index.js
:
{
path: '/owner/list',
name: 'OwnerList',
component: OwnerList
},
{
path: '/owner/create',
name: 'OwnerCreate',
component: OwnerCreate
},
{
path: '/owner/:id',
name: 'OwnerDetails',
component: OwnerDetails
},
Важно разместить наш маршрут над маршрутом OwnerDetails
. Если мы разместим его ниже, то при доступе к маршруту /owner/create
будет запущен маршрут OwnerDetails
, потому что часть маршрута create
будет распознаваться как параметр :id
.
И наконец, давайте изменим компонент src/components/Owner/OwnerList.vue
:
<template>
<div>
<b-row>
<b-col
md="2"
offset-md="10">
<router-link :to="{ name: 'OwnerCreate' }">Create owner</router-link>
</b-col>
</b-row>
....
Тег <router-link>
создаст тег <a>
, но не будет инициировать процесс перенаправления при нажатии, он только запустит vue-router
для переключения маршрута.
Теперь давайте запустим терминал и введем команду npm run dev
, чтобы проверить, все ли в порядке:
Когда мы вводим действительные данные и нажимаем кнопку Сохранить
:
Редактирование объекта-владельца
Форма редактирования почти идентична форме создания. Есть только несколько отличий. У нас есть параметр :id
в маршруте, и мы должны получить данные для этого владельца из серверной части и отобразить их в форме. Как только мы нажмем кнопку Сохранить
, мы отправим запрос PUT
на серверную часть с новыми данными для этого владельца.
Давайте создадим новый компонент OwnerUpdate.vue
внутри каталога src/components/Owner
. Единственная разница между этим шаблоном и шаблоном для создания владельца - это имя обработчика событий для формы отправки. В этом случае давайте просто скопируем шаблон из OwnerCreate.vue
и вставим его в новый компонент и отредактируем имя обработчика событий:
<template>
<b-container fluid>
<div class="form-wrapper">
<b-form @submit.prevent="updateOwner">
<b-form-group
:label-cols="2"
breakpoint="md"
...
</template>
В части скрипта у нас те же данные, что и в предыдущем компоненте. Более того, обработчик событий для кнопки ok
модального окна такой же. Мы собираемся реализовать логику получения владельца в созданном хуке жизненного цикла и для метода updateOwner
.
Итак, давайте реализуем сценарий для OwnerUpdate.vue
:
<script>
import OwnerService from '@/api-services/owner.service';
export default {
name: 'OwnerUpdate',
data() {
return {
formData: {
name: '',
dateOfBirth: '',
address: ''
},
alertModalTitle: '',
alertModalContent: '',
isSuccessfully: false
};
},
created() {
OwnerService.get(this.$router.currentRoute.params.id).then((response) => {
this.formData.name = response.data.name;
this.formData.dateOfBirth = response.data.dateOfBirth.split('T')[0];
this.formData.address = response.data.address;
});
},
methods: {
updateOwner() {
OwnerService.update(this.$router.currentRoute.params.id, this.formData).then(() => {
this.isSuccessfully = true;
this.alertModalTitle = 'Successfully';
this.alertModalContent = 'Successfully updated Account Owner';
this.$refs.alertModal.show();
}).catch((error) => {
this.isSuccessfully = false;
this.alertModalTitle = 'Error';
this.alertModalContent = error.response.data;
this.$refs.alertModal.show();
});
},
onAlertModalOkClick() {
if (this.isSuccessfully) {
this.$router.push({ name: 'OwnerList' });
}
}
}
};
</script>
Также определим маршрут для этого компонента:
{
path: '/owner/create',
name: 'OwnerCreate',
component: OwnerCreate
},
{
path: '/owner/update/:id',
name: 'OwnerUpdate',
component: OwnerUpdate
},
{
path: '/owner/:id',
name: 'OwnerDetails',
component: OwnerDetails
},
И наконец, нам нужно направить пользователя на эту страницу, когда пользователь нажимает кнопку Обновить
в компоненте OwnerList
:
updateOwner(ownerId) {
this.$router.push({ name: 'OwnerUpdate', params: { id: ownerId } });
},
Давайте снова наберем команду npm run dev
в терминале и посмотрим на результаты:
Когда мы нажимаем кнопку Обновить
в компоненте OwnerList, мы будем перенаправлены на новый компонент, и форма будет заполнена фактическими данными:
Давайте попробуем изменить наши поля ввода и нажать кнопку Сохранить
. Появится модальное окно:
И мы обновили сущность Owner в компоненте OwnerList.
Заключение
Прочитав этот пост, вы узнали:
- Как работает двусторонняя привязка
- Как предотвратить поведение событий по умолчанию
- Способ обработки запроса POST
- Способ обработки запроса PUT