Код отображения заголовков:
<div class="flex-column">
<div v-for="(book, index) in books.results" :key="index"
class="flex leading-6 mb-space-m cursor-pointer" @click="openModal(book)">
<h5>{{ index + 1 }}. {{ book.title }}</h5>
</div>
</div>
При нажатии на заголовок открывается модально окно, с информацией о книге, которое реализовано отдельным компонентом, оно же используется во всём приложении и изменениям не подлежит:
<ModalDesktop v-if="showModal" @close="closeModal">
<div v-if="selectedBook" class="px-space-s">
<div v-if="showBookDetails">
<img :src="`https://api.storage/${selectedBook.cover_path}`" alt="Cover"
class="w-[px] h-[100px] bg-center bg-cover" />
<h4>{{ selectedBook.title }}</h4>
<p><strong>Описание:</strong> {{ selectedBook.description }}</p>
<p>
<strong>Год публикации:</strong>
{{ selectedBook.published_year }}
</p>
<p><strong>Серия:</strong> {{ selectedBook.book_series }}</p>
<p><strong>Жанр:</strong> {{ selectedBook.genre }}</p>
<p><strong>Автор:</strong> {{ selectedBook.authors }}</p>
<p><strong>Тег:</strong> {{ selectedBook.tag_id }}</p>
<p><strong>Id книги:</strong> {{ selectedBook.id }}</p>
</div>
<div v-if="isBookDeleted">
<p>Книга успешно удалена!</p>
</div>
<div class="flex gap-x-space-s mt-space-s ml-auto">
<button v-if="showBookDetails"
class="bg-blue-500 text-white p-space-xs pl-space-m pr-space-m rounded-medium hover:bg-blue-600"
@click="deleteBook">
Удалить
</button>
</div>
</div>
</ModalDesktop>
Есть скрипт который получает, отображает и удаляет данные с апи:
<script setup lang="ts">
import { ref, watch } from "vue";
import ModalDesktop from "~/components/modals/ModalDesktop.vue";
const { data: books, refresh } = await useFetch<{ results: Book[] }>(
() => `https://api.storage`
);
interface Book {
title: string;
published_year: number;
description: string;
book_series: string;
genre: string;
authors: string;
tag_id: string;
id: string;
}
const showModal = ref(false);
const selectedBook = ref(null);
const isBookDeleted = ref(false);
const showBookDetails = ref(true);
const openModal = (book: any) => {
selectedBook.value = book;
showModal.value = true;
};
const closeModal = () => {
showModal.value = false;
selectedBook.value = null;
};
const { apiErrorHandler } = useErrorService();
const token =
"eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIwY2Y5Nzk0Yi1jYjczLTR";
const deleteBook = async () => {
const bookId = selectedBook.value.id;
const { error } = await useFetch(
`https://api.storage/${bookId}`,
{
method: "DELETE",
headers: {
Authorization: `Bearer ${token}`,
},
watch: [isBookDeleted],
}
);
if (error.value) {
apiErrorHandler(error.value);
} else {
isBookDeleted.value = true;
showBookDetails.value = false;
}
};
watch(isBookDeleted, (newValue) => {
if (newValue) {
refresh();
}
});
</script>
Данный код работает, строчки с заголовками отображаются, при нажатии на заголовок открывается модалка с подробной информацией о книге, из базы удаляются, но при удалении модалка с успешным удалением появляется на секунду, сама закрывается и далее обновляется страница, соответственно с текущей вкладки списка книг пользователя переносит на дефолтный экран (на той же странице). Пытаюсь реализовать функционал, чтобы при удалении появлялось модалка с успехом, пользователь самостоятельно её закрывает и далее видит тот же список, но уже без удалённой строчки. Реактивное обновление, что ли. В доке этот метод называется refetch, как настроить его правильно пока не разобрался.