feat: 初始化慧遇书院官网一期
This commit is contained in:
10
app/pages/products/[slug].vue
Normal file
10
app/pages/products/[slug].vue
Normal file
@@ -0,0 +1,10 @@
|
||||
<script setup lang="ts">
|
||||
const route = useRoute()
|
||||
const { site, isPreview } = await useSiteDocument()
|
||||
const absoluteUrl = useAbsoluteUrl()
|
||||
const product = computed(() => site.value.products.find(item => item.slug === route.params.slug && (isPreview.value ? item.status !== 'offline' : item.status === 'published')))
|
||||
if (!product.value) throw createError({ statusCode: 404, statusMessage: '未找到该课程或产品' })
|
||||
useSeoMeta({ title: () => `${product.value!.title}|${site.value.brand.name}`, description: () => product.value!.summary, ogTitle: () => product.value!.title, ogDescription: () => product.value!.summary, ogImage: () => absoluteUrl(product.value!.image) })
|
||||
useHead(() => ({ script: [{ type: 'application/ld+json', textContent: JSON.stringify({ '@context': 'https://schema.org', '@type': 'Course', name: product.value!.title, description: product.value!.summary, provider: { '@type': 'Organization', name: site.value.brand.companyName, url: absoluteUrl('/') }, image: absoluteUrl(product.value!.image) }) }] }))
|
||||
</script>
|
||||
<template><PublicPageLayout :site="site"><article v-if="product" class="story-page"><NuxtLink class="detail-back" :to="{ path: '/products', query: isPreview ? { preview: 'draft' } : {} }">← 返回课程与产品</NuxtLink><header><p class="eyebrow">{{ product.type === 'tool' ? 'TECH PRODUCT' : 'COURSE' }}</p><h1>{{ product.title }}</h1><p>{{ product.subtitle }}</p><img :src="product.image" :alt="product.title" width="1536" height="1024" loading="eager" decoding="async"></header><div class="story-body"><p class="lead">{{ product.summary }}</p><p class="long-copy">{{ product.content }}</p><a class="primary-button" href="/#contact">咨询了解</a></div></article></PublicPageLayout></template>
|
||||
6
app/pages/products/index.vue
Normal file
6
app/pages/products/index.vue
Normal file
@@ -0,0 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
const { site, isPreview } = await useSiteDocument()
|
||||
const products = computed(() => site.value.products.filter(item => isPreview.value ? item.status !== 'offline' : item.status === 'published'))
|
||||
useSeoMeta({ title: () => `课程与产品|${site.value.brand.name}`, description: () => `${site.value.brand.name}课程、服务与科技产品。`, ogTitle: () => `课程与产品|${site.value.brand.name}`, ogDescription: () => `${site.value.brand.name}课程、服务与科技产品。` })
|
||||
</script>
|
||||
<template><PublicPageLayout :site="site"><section class="listing-hero"><p class="eyebrow">COURSES & PRODUCTS</p><h1>课程与产品</h1><p>围绕关系、成长与日常实践,提供清晰、可持续的支持路径。</p></section><section class="listing-grid"><NuxtLink v-for="item in products" :key="item.slug" :to="{ path: `/products/${item.slug}`, query: isPreview ? { preview: 'draft' } : {} }" class="listing-card"><img :src="item.image" :alt="item.title" width="1536" height="1024" loading="lazy" decoding="async"><div><small>{{ item.type === 'tool' ? '科技工具' : '成长课程' }}</small><h2>{{ item.title }}</h2><p>{{ item.summary || item.subtitle }}</p><span>查看详情 →</span></div></NuxtLink></section></PublicPageLayout></template>
|
||||
Reference in New Issue
Block a user