Задать вопрос
@Soer44

Как правильно настроить refetch watch?

Код отображения заголовков:
<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, как настроить его правильно пока не разобрался.
  • Вопрос задан
  • 138 просмотров
Подписаться 1 Средний Комментировать
Пригласить эксперта
Ответы на вопрос 1
@null_object
<script setup lang="ts">
import ModalDesktop from "~/components/modals/ModalDesktop.vue";

interface Book {
  title: string;
  published_year: number;
  description: string;
  book_series: string;
  genre: string;
  authors: string;
  tag_id: string;
  id: string;
}

const token =
  "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIwY2Y5Nzk0Yi1jYjczLTR";

const { data: books, refresh } = await useFetch<{ results: Book[] }>(
  "https://api.storage",
);

const { apiErrorHandler } = useErrorService();

const selectedBook = ref<Book | null>(null);
const showDeleteModal = ref(false);

const modalVisible = computed(
  () => selectedBook.value !== null || showDeleteModal.value,
);

const openModal = (book: Book) => {
  selectedBook.value = book;
};

const closeModal = () => {
  selectedBook.value = null;
  showDeleteModal.value = false;
};

const deleteBook = async (book: Book) => {
  const { error } = await useFetch(`https://api.storage/${book.id}`, {
    method: "DELETE",
    headers: {
      Authorization: `Bearer ${token}`,
    },
  });

  if (error.value) {
    apiErrorHandler(error.value);
  } else {
    showDeleteModal.value = true;
    selectedBook.value = null;
  }
};
</script>


<ModalDesktop v-if="modalVisible" @close="closeModal">
    <div class="px-space-s">
      <div v-if="selectedBook">
        <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="showDeleteModal">
        <p>Книга успешно удалена!</p>
      </div>
      <div class="flex gap-x-space-s mt-space-s ml-auto">
        <button
          v-if="selectedBook"
          class="bg-blue-500 text-white p-space-xs pl-space-m pr-space-m rounded-medium hover:bg-blue-600"
          @click="deleteBook(selectedBook)"
        >
          Удалить
        </button>
      </div>
    </div>
  </ModalDesktop>
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы