Skip to content

Commit 38be91a

Browse files
committed
feat(blog): 添加博客文章列表组件并优化页面布局
在博客页面中新增了 `BlogPosts` 组件,用于展示文章列表。同时优化了页面布局,使用容器和网格系统来提升页面的可读性和美观性。通过 SolidJS 的资源加载功能,动态获取并渲染文章数据,支持加载状态和空状态的处理。
1 parent 86b7bc8 commit 38be91a

File tree

2 files changed

+123
-3
lines changed

2 files changed

+123
-3
lines changed
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
import { createResource, For, Show } from 'solid-js';
2+
import http from '@/lib/axios';
3+
4+
// 定义文章接口
5+
interface Post {
6+
id: string;
7+
title: string;
8+
slug: string;
9+
excerpt: string | null;
10+
featured_image: string | null;
11+
published: boolean;
12+
author_id: string;
13+
created_at: string;
14+
updated_at: string;
15+
published_at: string;
16+
labels: string[];
17+
}
18+
19+
// 格式化日期函数
20+
function formatDate(dateString: string) {
21+
const date = new Date(dateString);
22+
return date.toLocaleDateString("zh-CN", {
23+
year: "numeric",
24+
month: "long",
25+
day: "numeric",
26+
});
27+
}
28+
29+
// 获取文章数据的函数
30+
async function fetchPosts(): Promise<Post[]> {
31+
try {
32+
const response = await http.get<Post[]>("/posts");
33+
34+
// 检查响应格式,直接处理返回的数组数据
35+
if (response && Array.isArray(response)) {
36+
// 成功获取数据,API直接返回了文章数组
37+
return response.map((post) => ({
38+
...post,
39+
featured_image: post.featured_image
40+
? post.featured_image.replace(/`/g, "").trim()
41+
: null,
42+
}));
43+
} else {
44+
// 响应格式不符合预期
45+
console.error('API响应格式不符合预期:', response);
46+
return [];
47+
}
48+
} catch (error) {
49+
console.error('获取文章失败:', error);
50+
return [];
51+
}
52+
}
53+
54+
export default function BlogPosts() {
55+
// 使用SolidJS的资源加载功能获取文章
56+
const [posts] = createResource<Post[]>(fetchPosts);
57+
return (
58+
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 my-8">
59+
<Show when={!posts.loading} fallback={<div class="col-span-full text-center">加载中...</div>}>
60+
<Show
61+
when={posts() && posts().length > 0}
62+
fallback={
63+
<div class="col-span-full text-center py-12">
64+
<div class="alert alert-info shadow-lg max-w-md mx-auto">
65+
<svg
66+
xmlns="http://www.w3.org/2000/svg"
67+
fill="none"
68+
viewBox="0 0 24 24"
69+
class="stroke-current shrink-0 w-6 h-6"
70+
>
71+
<path
72+
stroke-linecap="round"
73+
stroke-linejoin="round"
74+
stroke-width="2"
75+
d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"
76+
/>
77+
</svg>
78+
<span>暂无文章,敬请期待!</span>
79+
</div>
80+
</div>
81+
}
82+
>
83+
<For each={posts()}>
84+
{(post) => (
85+
<div class="card bg-base-100 shadow-xl hover:shadow-2xl transition-shadow duration-300">
86+
{post.featured_image && post.featured_image.trim() !== "" && (
87+
<figure>
88+
<img src={post.featured_image} alt={post.title} class="w-full h-48 object-cover" />
89+
</figure>
90+
)}
91+
<div class="card-body">
92+
<h2 class="card-title">{post.title}</h2>
93+
<p class="text-sm opacity-70">{formatDate(post.published_at)}</p>
94+
<p class="mt-2">{post.excerpt || ""}</p>
95+
{post.labels && post.labels.length > 0 && (
96+
<div class="card-actions justify-start mt-3">
97+
{post.labels.map((tag) => (
98+
<div class="badge badge-outline">{tag}</div>
99+
))}
100+
</div>
101+
)}
102+
<div class="card-actions justify-end mt-4">
103+
<a href={`/blog/${post.id}`} class="btn btn-primary btn-sm">阅读更多</a>
104+
</div>
105+
</div>
106+
</div>
107+
)}
108+
</For>
109+
</Show>
110+
</Show>
111+
</div>
112+
);
113+
}
Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
---
2+
export const prerender = false;
23
import Layout from "@/layouts/Layout.astro";
4+
import BlogPosts from "@/components/solid/BlogPosts";
35
---
46

57
<Layout title="博客 | 精致的芯 - 精致的私人博客">
6-
<div class="text-left my-8">
7-
<h1 class="text-4xl font-bold">博客文章</h1>
8-
<p class="mt-2 text-lg">探索我的最新文章和想法</p>
8+
<div class="container mx-auto px-4">
9+
<div class="text-left my-8">
10+
<h1 class="text-4xl font-bold">博客文章</h1>
11+
<p class="mt-2 text-lg">探索我的最新文章和想法</p>
12+
</div>
13+
14+
<!-- 文章列表 -->
15+
<BlogPosts client:load />
916
</div>
1017
</Layout>

0 commit comments

Comments
 (0)