export default defineNuxtConfig({
hooks: {
'vite:extendConfig': function (vite) {
vite.server.hmr = {
protocol: 'wss',
};
},
},
});
<NuxtPage />
и не является проблемой, он внутри себя использует <RouterView />
из vue-router в который добавляется внутренняя логика Nuxt (например добавление Transitions если они указаны в настройках). Anonymous Component на самом деле - компонент RouteProvider
, который занимается перерисовкой страниц. В общем, просто обертка фреймворка для роутинга.const nuxtApp = useNuxtApp();
const loadingStartHook = nuxtApp.hook('page:loading:start', () => {
...
});
const loadingFinishHook = nuxtApp.hook('page:loading:end', () => {
...
});
const unsubError = nuxtApp.hook('vue:error', () => ...)
const { progress, isLoading } = useLoadingIndicator();
serverSupabaseClient
возвращает Promise, нужно добавить await
import { serverSupabaseClient } from '#supabase/server'
export default eventHandler(async (event) => {
const client = await serverSupabaseClient(event)
const { data } = await client.from('users').select("*")
return { users: data }
})
:
export default defineNuxtConfig({
hooks: {
"pages:extend"(pages) {
pages.push({
name: "cities-id",
path: "/cities/:id",
file: "~/pages/cities.vue",
});
},
},
});
<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>
import {
AddBookForm,
AddTagsForm,
AddAuthorsForm,
AddSeriesForm,
AddFilesForm
AddFoldersForm,
} from '#components'
const buttons = [
{ formName: resolveComponent('AddBookForm'), label: 'Добавить книгу' },
{ formName: resolveComponent('AddTagsForm'), label: 'Добавить ТЕГ' },
{ formName: resolveComponent('AddAuthorsForm'), label: 'Добавить Автора' },
{ formName: resolveComponent('AddSeriesForm'), label: 'Добавить Серию' },
{ formName: resolveComponent('AddFilesForm'), label: 'Добавить Файл' },
{ formName: resolveComponent('AddFoldersForm'), label: 'Добавить Папку' },
];