В предыдущей части мы узнали, как создавать и прослушивать события. Мы реализовали функции для всех трех кнопок, которые генерируют настраиваемые события с именами details
, update
и delete
, и теперь мы собираемся реализовать функции для этих событий.
Создание компонента сведений о владельце
В предыдущей части мы создали настраиваемое событие details
и слушатель для этого события. В обработчике событий мы использовали параметр id
из объекта owner
, и теперь мы собираемся использовать этот id
, чтобы получить данные о владельце. Для этого нам нужно создать новый компонент, в котором мы собираемся отображать данные владельца.
Создание компонента
Давайте перейдем в каталог src/components/owner
и создадим файл OwnerDetails.vue
:
<template>
<div>
<div class="well">
<div class="row">
<div class="col-md-3">
<strong>Owner name:</strong>
</div>
<div class="col-md-3">
{{ owner.name }}
</div>
</div>
<div class="row">
<div class="col-md-3">
<strong>Date of birth:</strong>
</div>
<div class="col-md-3">
{{ owner.dateOfBirth }}
</div>
</div>
<div
v-if="owner.accounts && owner.accounts.length <= 2"
class="row">
<div class="col-md-3">
<strong>Type of user:</strong>
</div>
<div class="col-md-3">
<span class="text-success">Beginner user.</span>
</div>
</div>
<div
v-else
class="row">
<div class="col-md-3">
<strong>Type of user:</strong>
</div>
<div class="col-md-3">
<span class="text-info">Advanced user.</span>
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Account type</th>
<th>Date created</th>
</tr>
</thead>
<tbody>
<tr
v-for="account in owner.accounts"
:key="account.id">
<td>{{ account.accountType }}</td>
<td>{{ account.dateCreated }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</template>
<script>
import OwnerService from '@/api-services/owner.service';
export default {
name: 'OwnerDetails',
data() {
return {
owner: {}
};
},
created() {
OwnerService.getAccounts(this.$router.currentRoute.params.id).then((response) => {
this.owner = response.data;
});
}
};
</script>
Фрагмент кода не требует пояснений, но давайте проанализируем его.
Описание кода компонента
У нас есть шаблон с некоторыми интерполяциями для отображения имени владельца, дня рождения и т. д. Также существует условный рендеринг, который условно отображает Beginner user
или Advanced user
текст на основе количества учетных записей, связанных с организацией-владельцем. Внутри блока script у нас есть хук жизненного цикла created
, в котором мы извлекаем id
владельца из строки запроса с this.$router.currentRoute.params.id
, а затем получаем данные из серверной части для этого владельца.
Реализация службы API и маршрутизация к компоненту
Теперь давайте создадим метод getAccounts
в OwnerService
:
...
delete(id) {
return Axios.delete(`${RESOURCE_NAME}/${id}`);
},
getAccounts(id) {
return Axios.get(${RESOURCE_NAME}/${id}/account);
}
Нам все еще нужно создать маршрут для этого компонента.
Для этого мы собираемся отредактировать файл src/router/index.js
:
{
path: '/owner/list',
name: 'OwnerList',
component: OwnerList
},
{
path: '/owner/:id',
name: 'OwnerDetails',
component: OwnerDetails
},
{
path: '*',
name: 'NotFound',
component: NotFound
}
Мы только что определили новый маршрут, который будет принимать id
в качестве параметра в строке запроса. Мы можем получить доступ к параметрам маршрута в наших компонентах через объект this.$router.currentRoute.params
.
Наконец, нам нужно перейти к этому компоненту, когда мы нажмем кнопку Details
в таблице списка владельцев.
Давайте отредактируем файл src/components/owner/OwnerList.vue
:
detailsOwner(ownerId) {
this.$router.push({ name: 'OwnerDetails', params: { id: ownerId } });
},
Теперь откройте терминал и введите команду npm run dev
, чтобы посмотреть результаты:
Все выглядит идеально.
Теперь давайте реализуем функцию Delete
.
Удаление объекта-владельца
Когда пользователь нажимает кнопку Delete
, должно открываться диалоговое окно подтверждения. Если мы подтвердим действие удаления, на сервер будет отправлен запрос. Сервер может ответить кодом состояния 204 (Нет содержимого), что означает, что мы успешно удалили объект-владелец.
В противном случае сервер может ответить одним из сообщений об ошибке, в зависимости от того, что пошло не так. В обоих случаях мы отобразим модальное окно, которое сообщит нам, было ли наше действие успешным или нет.
Теперь попробуем создать два модальных окна. Одно из них - модальное окно подтверждения, которое имеет статическое содержимое, а второе - модальное окно, информирующее нас об ответе на запрос на удаление. Итак, во втором окне мы собираемся реализовать привязку данных, потому что нам нужно отображать разные сообщения в зависимости от ответа сервера.Создание компонента
Давайте перейдем к компоненту OwnerList.vue
и реализуем это действие привязки данных:
<template>
<div>
<b-row>
<b-col
md="2"
offset-md="10">
<a href="#">Create owner</a>
</b-col>
</b-row>
<br>
<b-row>
<b-col md="12">
<div class="table-responsive">
<table class="table table-striped">
<thead>
<tr>
<th>Owner name</th>
<th>Owner address</th>
<th>Date of birth</th>
<th>Details</th>
<th>Update</th>
<th>Delete</th>
</tr>
</thead>
<tbody>
<owner-list-row
v-for="owner in owners"
:key="owner.id"
:owner="owner"
@details="detailsOwner"
@update="updateOwner"
@delete="deleteOwner"/>
</tbody>
</table>
</div>
</b-col>
</b-row>
<b-modal
ref="deleteConfirmModal"
title="Confirm your action"
@ok="onDeleteConfirm"
@hide="onDeleteModalHide">
<p class="my-4">Are you sure you want to delete this owner?</p>
</b-modal>
<b-modal
ref="alertModal"
:title="alertModalTitle"
:ok-only="true">
<p class="my-4">{{ alertModalContent }}</p>
</b-modal>
</div>
</template>
<script>
import OwnerService from '@/api-services/owner.service';
import OwnerListRow from '@/components/owner/OwnerListRow';
export default {
name: 'OwnerList',
components: {
OwnerListRow
},
data() {
return {
owners: [],
selectedOwnerId: null,
alertModalTitle: '',
alertModalContent: ''
};
},
created() {
this.fetchOwners();
},
methods: {
detailsOwner(ownerId) {
this.$router.push({ name: 'OwnerDetails', params: { id: ownerId } });
},
updateOwner(ownerId) {
console.log('update', ownerId);
},
deleteOwner(ownerId) {
this.selectedOwnerId = ownerId;
this.$refs.deleteConfirmModal.show();
},
fetchOwners() {
OwnerService.getAll().then((response) => {
this.owners = response.data;
});
},
onDeleteConfirm() {
OwnerService.delete(this.selectedOwnerId).then(() => {
this.alertModalTitle = 'Successfully';
this.alertModalContent = 'Successfully deleted Account Owner';
this.$refs.alertModal.show();
this.fetchOwners();
}).catch((error) => {
this.alertModalTitle = 'Error';
this.alertModalContent = error.response.data;
this.$refs.alertModal.show();
});
},
onDeleteModalHide() {
this.selectedOwnerId = null;
}
}
};
</script>
Описание кода компонента
Мы переместили логику выборки владельца из обработчика жизненного цикла created
в метод с именем fetchOwners
. Мы сделали это по причине того, что нам нужно снова получить всех владельцев после успешного удаления одного владельца. Теперь, когда мы переместили логику в метод, мы можем повторно использовать наш код владельца выборки.
Далее мы создаем несколько переменных. В переменной selectedOwnerId
мы собираемся сохранить параметр id
от сущности-владельца, которую мы хотим удалить. В оставшихся двух переменных мы сохраним заголовок и содержимое второго модального окна.
Давайте посмотрим на конструкцию this.$refs
, которую мы используем впрервые
В части шаблона у нас есть два модальных окна. В обоих модальных окнах у нас есть атрибут ref="something"
. Так же, как мы можем получить элемент в обычном JavaScript с помощью выражения document.getElementById()
, мы можем получить ссылку на элемент (или другой компонент vue, в данном случае b-modal) в Vue.js с помощью операторов ref
и this.$refs
. Мы можем использовать эти ссылки на модальные окна для запуска внутри них метода show()
. Остальная часть шаблона не требует пояснений.
Проверка результатов
Давайте снова откроем терминал и запустим команду npm run dev
для просмотра результатов.
Если мы попытаемся удалить Anna Bosh
, появится модальное окно подтверждения:
Когда мы нажимаем кнопку OK
, появляется ошибка, потому что у Anna Bosh
есть связанные учетные записи:
Если мы попытаемся удалить Nick Somion
, снова появится диалоговое окно подтверждения:
И появляется сообщение successfully
, что значит "успешно":
Заключение
Прочитав этот пост, вы узнали:
- Как обрабатывать ошибки сервера
- Как ссылаться на элементы или компоненты из шаблона
- Как создать диалог подтверждения действия