88 lines
3.5 KiB
Vue
88 lines
3.5 KiB
Vue
<template>
|
|
<div class="w-full bg-gray-50 dark:bg-gray-900 min-h-screen p-2 sm:p-4 lg:p-2">
|
|
<!-- 响应式卡片网格 -->
|
|
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4 max-w-8xl mx-auto">
|
|
<div v-for="item in firstLevelItems" :key="item.path"
|
|
class="bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700 p-5 sm:p-6 shadow-sm hover:shadow-md transition-all duration-200 cursor-pointer"
|
|
@click="navigateTo(item.path)">
|
|
|
|
<!-- 卡片头部 -->
|
|
<div class="flex items-center justify-between mb-1">
|
|
<h2 class="text-xl sm:text-xl lg:text-2xl font-bold text-gray-900 dark:text-white leading-tight">
|
|
{{ item.title }}
|
|
</h2>
|
|
<span class="text-sm sm:text-base lg:text-lg text-gray-600 dark:text-gray-400 font-normal">
|
|
<sum class="text-primary mr-0.3">{{ getChildrenCount(item) }}</sum>篇
|
|
</span>
|
|
</div>
|
|
|
|
<!-- 子页面列表 -->
|
|
<div v-if="getChildrenTitles(item).length > 0" class="">
|
|
<div v-for="(child, index) in getChildrenWithIcons(item).slice(0, 5)" :key="index"
|
|
class="flex items-center justify-between
|
|
text-sm sm:text-base lg:text-lg text-gray-700 dark:text-gray-300
|
|
hover:text-blue-600 dark:hover:text-blue-400
|
|
transition-colors duration-200 py-1
|
|
border-b border-gray-200 dark:border-gray-700 pt-2">
|
|
|
|
<div class="flex items-center flex-1 min-w-0 pl-1 ">
|
|
<Icon :name="child.icon || 'i-lucide-file-text'" class="mr-2 text-gray-400" size="14" />
|
|
<span class="text-base font-sans">{{ child.title }}</span>
|
|
</div>
|
|
<Icon name="i-lucide-chevron-right" class="text-gray-400 flex-shrink-0 ml-2" size="16" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import type { ContentNavigationItem } from "@nuxt/content";
|
|
|
|
const navigation = inject<Ref<ContentNavigationItem[]>>("navigation");
|
|
|
|
// 计算属性:提取第一级数据
|
|
const firstLevelItems = computed(() => {
|
|
if (!navigation?.value) return [];
|
|
return navigation.value
|
|
.filter(item => item.title && item.path)
|
|
.map(item => ({
|
|
...item,
|
|
description: item.description,
|
|
icon: item.icon || 'i-lucide-book-open'
|
|
}));
|
|
});
|
|
|
|
// 获取子页面数量
|
|
const getChildrenCount = (item: ContentNavigationItem) => {
|
|
return item.children?.length || 0;
|
|
};
|
|
|
|
// 获取子页面标题列表
|
|
const getChildrenTitles = (item: ContentNavigationItem) => {
|
|
if (!item.children) return [];
|
|
return item.children.map(child => child.title).filter(Boolean);
|
|
};
|
|
|
|
// 获取子页面数据(包含图标)
|
|
const getChildrenWithIcons = (item: ContentNavigationItem) => {
|
|
if (!item.children) return [];
|
|
return item.children.filter(child => child.title);
|
|
};
|
|
|
|
// 获取描述信息
|
|
const getDescription = (item: ContentNavigationItem) => {
|
|
if (item.children && item.children.length > 0) {
|
|
return `${item.children.length} 个子页面`;
|
|
}
|
|
return "文档页面";
|
|
};
|
|
|
|
// 导航方法
|
|
const navigateTo = (path: string) => {
|
|
if (path) {
|
|
window.location.href = path;
|
|
}
|
|
};
|
|
</script> |