95 lines
3.7 KiB
Vue
95 lines
3.7 KiB
Vue
<script setup lang="ts">
|
|
import type { SectionBlock, SpecGroup } from '~/types/site';
|
|
|
|
const props = defineProps<{ section: SectionBlock }>();
|
|
|
|
const { overline, title, subtitle, isEn, isDark } = useSectionContent(props.section);
|
|
|
|
const specGroups = computed<SpecGroup[]>(() => props.section.spec_groups ?? []);
|
|
|
|
// 每个分组的展开状态(默认收起,仅显示前 default_visible 项)
|
|
const expandedMap = ref<Record<number, boolean>>({});
|
|
|
|
function isExpanded(group: SpecGroup): boolean {
|
|
return !!expandedMap.value[group.id];
|
|
}
|
|
|
|
function toggle(group: SpecGroup) {
|
|
expandedMap.value[group.id] = !expandedMap.value[group.id];
|
|
}
|
|
|
|
// 分组内可见的参数项:展开时全部,收起时前 default_visible 项
|
|
function visibleItems(group: SpecGroup) {
|
|
const items = group.items ?? [];
|
|
if (isExpanded(group)) return items;
|
|
return items.slice(0, group.default_visible || 5);
|
|
}
|
|
|
|
// 是否需要显示展开按钮(参数项 > 默认显示数量)
|
|
function needToggle(group: SpecGroup): boolean {
|
|
return (group.items?.length ?? 0) > (group.default_visible || 5);
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="section-container py-96px">
|
|
<!-- 标题区 -->
|
|
<div class="text-center max-w-640px mx-auto mb-56px">
|
|
<p v-if="overline" class="text-13px font-semibold tracking-widest uppercase" :class="isDark ? 'text-primary-300' : 'text-primary'">
|
|
{{ overline }}
|
|
</p>
|
|
<h2 class="mt-12px text-3xl md:text-4xl font-bold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
|
|
{{ title }}
|
|
</h2>
|
|
<p v-if="subtitle" class="mt-16px text-base" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'">
|
|
{{ subtitle }}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- 参数分组卡片 -->
|
|
<div class="flex flex-col gap-24px max-w-960px mx-auto">
|
|
<div
|
|
v-for="group in specGroups"
|
|
:key="group.id"
|
|
class="rounded-16px overflow-hidden"
|
|
:class="isDark ? 'bg-white/5 border border-white/10' : 'bg-white border border-gray-100 shadow-sm dark:bg-dark-800 dark:border-dark-700'"
|
|
>
|
|
<!-- 分组标题 -->
|
|
<div class="px-32px py-20px border-b" :class="isDark ? 'border-white/10' : 'border-gray-100 dark:border-dark-700'">
|
|
<h3 class="text-lg font-semibold" :class="isDark ? 'text-white' : 'text-gray-900 dark:text-white'">
|
|
{{ isEn ? group.title_en : group.title_zh }}
|
|
</h3>
|
|
</div>
|
|
|
|
<!-- 参数项列表 -->
|
|
<div class="px-32px">
|
|
<div
|
|
v-for="item in visibleItems(group)"
|
|
:key="item.id"
|
|
class="flex items-start justify-between gap-24px py-14px border-b last:border-b-0"
|
|
:class="isDark ? 'border-white/5' : 'border-gray-50 dark:border-dark-700/50'"
|
|
>
|
|
<span class="text-sm shrink-0" :class="isDark ? 'text-gray-400' : 'text-gray-500 dark:text-gray-400'">
|
|
{{ isEn ? item.name_en : item.name_zh }}
|
|
</span>
|
|
<span class="text-sm text-right font-medium" :class="isDark ? 'text-gray-200' : 'text-gray-800 dark:text-gray-200'">
|
|
{{ isEn ? item.value_en : item.value_zh }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 展开/收起按钮 -->
|
|
<div v-if="needToggle(group)" class="px-32px py-16px">
|
|
<button
|
|
class="text-sm font-medium transition-colors"
|
|
:class="isDark ? 'text-primary-300 hover:text-primary-200' : 'text-primary hover:opacity-80'"
|
|
@click="toggle(group)"
|
|
>
|
|
{{ isExpanded(group) ? '收起参数 ∧' : `查看全部参数(${group.items?.length ?? 0} 项)∨` }}
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|