migrate on nuxt3
This commit is contained in:
281
pages/books/[slug].vue
Normal file
281
pages/books/[slug].vue
Normal file
@ -0,0 +1,281 @@
|
||||
<template>
|
||||
<template v-if="book">
|
||||
<div class="relative z-50 min-h-screen text-white mb-[208px]">
|
||||
<template v-if="!route.params.titlesSlug">
|
||||
<!--верхний блок-->
|
||||
<section
|
||||
class="flex flex-row relative z-40 before:content-[''] before:absolute before:top-[-140px] before:bg-top before:left-0 before:w-[1280px] before:h-[1000px] before:bg-[url(/assets/img/webp/vino-galante.webp)] before:bg-no-repeat before:bg-contain mt-40"
|
||||
>
|
||||
<!--левый блок контента-->
|
||||
<section class="relative top-[-20px] min-w-[570px]">
|
||||
<div class="flex flex-col items-center">
|
||||
<img
|
||||
:src="book.img"
|
||||
:alt="book.buttonText"
|
||||
width="100%"
|
||||
height="100%"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
<!--правый блок контента-->
|
||||
<section>
|
||||
<div class="w-11/12 h-full flex flex-col justify-start">
|
||||
<div>
|
||||
<UiHeading
|
||||
tag="H1"
|
||||
class="whitespace-pre-line [&]:font-bold"
|
||||
size="300"
|
||||
>
|
||||
{{ book.title }}
|
||||
</UiHeading>
|
||||
<UiParagraph class="mb-10" size="250">
|
||||
{{ book.subtitle }}
|
||||
</UiParagraph>
|
||||
<UiParagraph size="250" class="mb-20">
|
||||
{{ book.subdesc }}
|
||||
</UiParagraph>
|
||||
<UiParagraph size="250" class="whitespace-pre-line min-h-62">
|
||||
{{ book.description }}
|
||||
</UiParagraph>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
<!--средний блок-->
|
||||
<section class="flex flex-row items-center ml-20 justify-between">
|
||||
<!--левый-->
|
||||
<div class="flex flex-col items-center min-h-[310px]">
|
||||
<div class="flex flex-row">
|
||||
<UiParagraph class="[&]:text-6xl"
|
||||
>{{ book.price }} </UiParagraph
|
||||
>
|
||||
<img src="/img/svg/books/ruble.svg" alt="ruble" />
|
||||
</div>
|
||||
<div class="mr-10 flex items-center flex-col gap-3">
|
||||
<UiButton class="max-w-[380px] !font-normal !px-2 !py-4 mt-24">
|
||||
{{ book.buttonText }}
|
||||
</UiButton>
|
||||
<UiParagraph size="200">
|
||||
{{ book.buttonFormat }}
|
||||
</UiParagraph>
|
||||
</div>
|
||||
</div>
|
||||
<!--правый-->
|
||||
<div class="min-h-[310px]">
|
||||
<!--о книге-->
|
||||
<div>
|
||||
<ul
|
||||
class="flex flex-row mr-14 items-center justify-between lg:whitespace-nowrap"
|
||||
>
|
||||
<li class="flex flex-row mr-14 gap-3 items-center">
|
||||
<img
|
||||
src="/img/svg/books/book-pages.svg"
|
||||
alt="страниц"
|
||||
width="100%"
|
||||
height="100%"
|
||||
/>
|
||||
<UiParagraph size="250" as="span">
|
||||
{{ book.pages }}
|
||||
</UiParagraph>
|
||||
</li>
|
||||
<li class="flex flex-row mr-14 gap-3 items-center">
|
||||
<img
|
||||
src="/img/svg/books/book-illustrations.svg"
|
||||
alt="иллюстраций"
|
||||
width="100%"
|
||||
height="100%"
|
||||
/>
|
||||
<UiParagraph size="250" as="span">
|
||||
{{ book.illust }}
|
||||
</UiParagraph>
|
||||
</li>
|
||||
<li class="flex flex-row mr-14 gap-3 items-center">
|
||||
<img
|
||||
src="/img/svg/books/book-formats.svg"
|
||||
alt="формат"
|
||||
width="100%"
|
||||
height="100%"
|
||||
/>
|
||||
<UiParagraph size="250" as="span">
|
||||
{{ book.format }}
|
||||
</UiParagraph>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!--навигация по книге-->
|
||||
<div class="mt-24">
|
||||
<ul
|
||||
class="flex flex-row mr-32 items-end justify-between lg:whitespace-nowrap"
|
||||
>
|
||||
<li class="flex flex-row items-center">
|
||||
<NuxtLink
|
||||
to="#"
|
||||
class="flex flex-col items-center cursor-pointer"
|
||||
>
|
||||
<div class="w-[62px] h-[58px]">
|
||||
<img
|
||||
src="/img/svg/books/read.svg"
|
||||
alt="Читай отрывок"
|
||||
width="62"
|
||||
height="53"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<UiParagraph size="250" as="span">
|
||||
Читай отрывок
|
||||
</UiParagraph>
|
||||
</NuxtLink>
|
||||
</li>
|
||||
<li class="flex flex-row gap-3 items-center">
|
||||
<NuxtLink
|
||||
to="#"
|
||||
class="flex flex-col items-center gap-4 cursor-pointer"
|
||||
>
|
||||
<div class="w-[62px] h-[53px]">
|
||||
<img
|
||||
src="/img/svg/books/download.svg"
|
||||
alt="Скачай отрывок"
|
||||
width="62"
|
||||
height="53"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<UiParagraph size="250" as="span">
|
||||
Скачай отрывок
|
||||
</UiParagraph>
|
||||
</NuxtLink>
|
||||
</li>
|
||||
<li class="flex flex-row gap-3 items-center">
|
||||
<NuxtLink
|
||||
:to="`/books/${route.params.slug}/${book.hrefTitles}`"
|
||||
class="flex flex-col items-center gap-3 cursor-pointer"
|
||||
>
|
||||
<div class="w-[62px] h-[53px]">
|
||||
<img
|
||||
src="/img/svg/books/down2.svg"
|
||||
alt="Содержание"
|
||||
width="62"
|
||||
height="53"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<UiParagraph size="250" as="span"> Содержание </UiParagraph>
|
||||
</NuxtLink>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<!--нижний блок-->
|
||||
<section class="ml-20 mt-32">
|
||||
<div>
|
||||
<UiHeading tag="H2" size="300" class="text-three">
|
||||
Что ты узнаешь
|
||||
</UiHeading>
|
||||
<ul class="flex mt-20 flex-row items-center justify-between">
|
||||
<li
|
||||
class="flex flex-col-reverse justify-end w-32 gap-4 h-64 items-center transition-transform transform hover:scale-110"
|
||||
v-for="({ svg, text }, index) in book.whoUKnows"
|
||||
:key="index"
|
||||
>
|
||||
<UiParagraph class="text-center" size="250">
|
||||
{{ text }}
|
||||
</UiParagraph>
|
||||
<img :src="`${svg}`" alt="Вопрос" width="45" height="45" />
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="flex justify-center text-center mt-36">
|
||||
<UiParagraph>
|
||||
Или купи на ЛитРес - <br /><a
|
||||
class="text-three"
|
||||
:href="book.href"
|
||||
target="_blank"
|
||||
>Реферальная ссылка для поддержки автора</a
|
||||
>
|
||||
</UiParagraph>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<NuxtPage />
|
||||
</div>
|
||||
</template>
|
||||
<div v-else class="text-white text-center py-20">Книга не найдена.</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, computed, watch } from "vue";
|
||||
import { useRoute } from "#app";
|
||||
import UiHeading from "@/components/Typography/UiHeading.vue";
|
||||
import UiParagraph from "@/components/Typography/UiParagraph.vue";
|
||||
import UiButton from "@/components/UiButton/UiButton.vue";
|
||||
|
||||
interface BookDetail {
|
||||
id: number;
|
||||
title: string;
|
||||
metaTitle: string;
|
||||
subtitle: string;
|
||||
subdesc: string;
|
||||
description: string;
|
||||
img: string;
|
||||
price: string;
|
||||
buttonText: string;
|
||||
buttonFormat: string;
|
||||
pages: string;
|
||||
illust: string;
|
||||
format: string;
|
||||
whoUKnows: Array<{
|
||||
text: string;
|
||||
svg: string;
|
||||
}>;
|
||||
href: string;
|
||||
hrefTitles: string;
|
||||
}
|
||||
|
||||
const route = useRoute();
|
||||
|
||||
const currentBookData = ref<BookDetail | null>(null);
|
||||
|
||||
const book = computed(() => currentBookData.value);
|
||||
|
||||
const loadBookData = async (slug: string) => {
|
||||
try {
|
||||
const module = await import(`./_data/${slug}.json`);
|
||||
currentBookData.value = module.default as BookDetail;
|
||||
} catch (error) {
|
||||
console.error(`Ошибка при загрузке книги с slug '${slug}':`, error);
|
||||
currentBookData.value = null;
|
||||
}
|
||||
};
|
||||
|
||||
watch(
|
||||
() => route.params.slug,
|
||||
async (newSlug) => {
|
||||
if (newSlug) {
|
||||
await loadBookData(newSlug as string);
|
||||
}
|
||||
},
|
||||
{ immediate: true }
|
||||
);
|
||||
|
||||
watch(book, (newBook) => {
|
||||
if (newBook) {
|
||||
useHead({
|
||||
title: `${newBook.metaTitle} | Vino Galante`,
|
||||
meta: [
|
||||
{
|
||||
name: "description",
|
||||
content: "Онлайн магазин книг автора Vino Galante",
|
||||
},
|
||||
],
|
||||
link: [
|
||||
{
|
||||
rel: "canonical",
|
||||
href: `https://ebook.miduway.space/books/${route.params.slug}`,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
Reference in New Issue
Block a user