@ -549,7 +549,6 @@ if (!yearChips.length) yearChips = yearSeed
|
||||
</style>
|
||||
|
||||
<script>
|
||||
import Alpine from "alpinejs"
|
||||
import { getArticles, getBrands, toAbs, type ArticleItem, type BrandEntry } from "@/lib/api"
|
||||
|
||||
const ICON_USER = `<svg viewBox="0 0 12 12" width="9" height="9" aria-hidden="true"><circle cx="6" cy="4" r="2" stroke="currentColor" fill="none" stroke-width="1"/><path d="M2 10c0-2 1.8-3 4-3s4 1 4 3" stroke="currentColor" fill="none" stroke-width="1" stroke-linecap="round"/></svg>`
|
||||
|
||||
@ -53,7 +53,7 @@ const homeHref = locale === "cn" ? "/cn" : "/en/"
|
||||
const archiveHref = locale === "cn" ? "/cn/shows" : "/en/shows"
|
||||
const crumbs: { label: string; href: string }[] = [
|
||||
{ label: "Home", href: homeHref },
|
||||
{ label: "Runway Archive", href: archiveHref },
|
||||
{ label: "Runway Looks", href: archiveHref },
|
||||
]
|
||||
if (article?.brand_id) {
|
||||
crumbs.push({
|
||||
@ -98,9 +98,6 @@ if (article?.brand_id) {
|
||||
</section>
|
||||
)}
|
||||
|
||||
<div class="mt-16 pt-6 border-t border-black">
|
||||
<a href={homeHref} class="text-[12px] font-mono uppercase tracking-widest hover:opacity-60 transition-opacity">{lbl.back}</a>
|
||||
</div>
|
||||
</article>
|
||||
) : (
|
||||
<div class="flex flex-col items-center justify-center min-h-[60vh] px-5 text-center">
|
||||
@ -137,7 +134,7 @@ if (article?.brand_id) {
|
||||
class="relative block w-full aspect-[3/4] mb-2 rounded-[2px] overflow-hidden cursor-pointer transition-all duration-200"
|
||||
:class="lbIndex === i ? 'opacity-100 scale-[1.03] ring-2 ring-[#111]' : 'opacity-40 hover:opacity-85'"
|
||||
>
|
||||
<img :src="im.url" alt="" class="w-full h-full object-cover block" />
|
||||
<img :src="im.url" alt="" loading="lazy" class="w-full h-full object-cover block" />
|
||||
<span
|
||||
class="absolute left-1 top-1 z-10 font-mono text-[8px] sm:text-[9px] font-semibold tracking-widest text-white px-1 py-0.5 rounded-[3px] bg-black/55 backdrop-blur-sm"
|
||||
:class="lbIndex === i ? '!bg-[#111]' : ''"
|
||||
@ -177,6 +174,7 @@ if (article?.brand_id) {
|
||||
:src="images[lbIndex].url"
|
||||
:alt="images[lbIndex].name || ''"
|
||||
@click="toggleZoom()"
|
||||
loading="lazy"
|
||||
class="block select-none transition-opacity duration-200"
|
||||
:class="lbZoomed ? 'w-full max-w-full h-auto max-h-none cursor-zoom-out' : 'max-w-full max-h-full object-contain cursor-zoom-in'"
|
||||
/>
|
||||
@ -198,6 +196,7 @@ if (article?.brand_id) {
|
||||
<!-- Alpine.js 业务逻辑:仅负责灯箱交互,图片数据由服务端注入 -->
|
||||
<script>
|
||||
document.addEventListener('alpine:init', () => {
|
||||
alert(1212)
|
||||
Alpine.data('articleView', (images = []) => ({
|
||||
images,
|
||||
lbOpen: false,
|
||||
|
||||
14
src/env.d.ts
vendored
Normal file
14
src/env.d.ts
vendored
Normal file
@ -0,0 +1,14 @@
|
||||
// 全局类型声明补充
|
||||
// @astrojs/alpinejs 集成会在运行时把 Alpine 挂到全局(window.Alpine),
|
||||
// 但 @types/alpinejs 是 CJS(export = Alpine),其顶层 declare const Alpine
|
||||
// 不会自动进入模块上下文(.astro 的 <script> 是模块),导致 IDE 报 “Cannot find name 'Alpine'”。
|
||||
// 这里用 namespace 导入取真实的 Alpine.Alpine 接口类型作为全局声明,
|
||||
// 既消除报错、又让 Alpine.data / .store / .magic 等方法以及 data 组件内的 this 都有完整提示。
|
||||
// 注意:@types/alpinejs 是 export = 形式,不能用默认导入(会解析成 namespace 而非类型)。
|
||||
import type * as Alpine from "alpinejs";
|
||||
|
||||
declare global {
|
||||
const Alpine: Alpine.Alpine;
|
||||
}
|
||||
|
||||
export {};
|
||||
@ -1,27 +0,0 @@
|
||||
---
|
||||
import Layout from "@/layouts/Layout.astro"
|
||||
import Article from "@/components/pages/article.astro"
|
||||
import { fetchArticleById } from "@/lib/data"
|
||||
|
||||
// 按需 SSR:服务端按 ?id= 取数并渲染(保留既有 /article?id= 链接,无需改动其他页面)
|
||||
export const prerender = false
|
||||
|
||||
const API = (import.meta.env.API_SSR || import.meta.env.PUBLIC_API_BASE || "http://localhost:8090").replace(/\/$/, "")
|
||||
const id = Astro.url.searchParams.get("id")
|
||||
let article: import("@/lib/data").RawArticle | null = null
|
||||
let error: "missing" | "failed" | null = null
|
||||
if (!id) {
|
||||
error = "missing"
|
||||
} else {
|
||||
try {
|
||||
article = await fetchArticleById(id, API)
|
||||
} catch {
|
||||
article = null
|
||||
}
|
||||
error = article ? null : "failed"
|
||||
}
|
||||
---
|
||||
|
||||
<Layout>
|
||||
<Article article={article} locale="en" apiBase={API} error={error} />
|
||||
</Layout>
|
||||
@ -1,6 +1,8 @@
|
||||
{
|
||||
"extends": "astro/tsconfigs/strict",
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"ignoreDeprecations": "6.0",
|
||||
"paths": {
|
||||
"@/*": ["./src/*"]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user