921 字
5 分钟
实现博客天气热搜卡片组件
HOPPINZQ

今天我完成了在hoppin博客项目中实现天气热搜卡片组件的任务。这个组件将显示当前的天气热搜信息,为博客增加了实用的实时数据展示功能。

🌟 任务概述#

我需要在博客的左侧边栏添加一个天气热搜卡片组件,主要功能包括:

  • 基于Figma原型开发UI
  • 集成hoppin天气热搜API
  • 实现数据获取和状态管理
  • 添加到左侧边栏组件

📁 项目结构#

hoppin博客项目基于Astro和Tailwind CSS开发,我主要修改了以下文件:

  • src/components/widget/WeatherHotSearch.astro - 新创建的天气热搜卡片组件
  • src/components/widget/LeftSideBar.astro - 在左侧边栏中引入新组件

🎨 组件设计#

UI设计#

天气热搜卡片组件采用了与博客现有组件一致的设计风格,使用了WidgetLayout作为容器,确保视觉统一性。组件包含:

  • 头部:显示标题和刷新图标
  • 内容区域:显示天气热搜列表
  • 加载状态:显示骨架屏
  • 错误状态:显示错误信息和重试按钮

数据结构#

interface WeatherHotSearchItem {
title: string;
link: string;
heat: string;
desc: string;
}
interface WeatherHotSearchResponse {
code: number;
data: WeatherHotSearchItem[];
message: string;
}

🔧 实现过程#

1. 创建组件文件#

首先,我在src/components/widget/目录下创建了WeatherHotSearch.astro文件。

2. 实现组件结构#

组件使用了Astro的混合语法,结合HTML和JavaScript:

---
// 导入依赖和类型定义
import WidgetLayout from './WidgetLayout.astro';
import Icon from '../misc/Icon.astro';
import { WEATHER_HOT_SEARCH_ICON } from '@constants/icon';
// 定义组件Props和状态
interface Props {
delay?: number;
}
const props = Astro.props;
let isLoading = true;
let error = null;
let data = [];
---
<WidgetLayout
title="天气热搜"
icon={WEATHER_HOT_SEARCH_ICON}
className="weather-hot-search"
delay={props.delay}
>
<!-- 组件内容 -->
</WidgetLayout>

3. 集成API#

使用fetch API调用hoppin天气热搜接口:

const API_URL = 'https://hoppinzq.com:9050/api/proxy/weather/hot-search';
async function fetchWeatherHotSearch() {
try {
isLoading = true;
error = null;
const response = await fetch(API_URL);
const result = await response.json();
if (result.code === 200) {
data = result.data;
} else {
throw new Error(result.message || '获取数据失败');
}
} catch (err) {
error = err.message;
} finally {
isLoading = false;
}
}
// 初始化加载数据
await fetchWeatherHotSearch();

4. 实现状态管理#

组件包含三种状态:

加载状态#

{#if isLoading}
<div class="space-y-3 animate-pulse">
{#each Array(5) as _, index}
<div class="flex items-center">
<div class="h-2 w-2 bg-gray-400 rounded-full mr-2"></div>
<div class="h-2 bg-gray-400 rounded-full flex-1"></div>
</div>
{/each}
</div>
{/if}

成功状态#

{#if !isLoading && !error && data.length > 0}
<ul class="space-y-3">
{#each data as item, index}
<li class="group">
<a href={item.link} target="_blank" rel="noopener noreferrer" class="flex items-start">
<span class="text-sm text-gray-500 dark:text-gray-400 mr-2">{index + 1}</span>
<span class="flex-1 text-sm text-gray-700 dark:text-gray-300 hover:text-primary dark:hover:text-primary group-hover:underline">
{item.title}
</span>
</a>
<p class="text-xs text-gray-500 dark:text-gray-400 mt-1 ml-4">
{item.desc}
</p>
<div class="text-xs text-gray-400 dark:text-gray-500 mt-1 ml-4 flex items-center">
<span class="w-1.5 h-1.5 bg-red-500 rounded-full mr-1"></span>
热度:{item.heat}
</div>
</li>
{/each}
</ul>
{/if}

错误状态#

{#if !isLoading && error}
<div class="text-center py-6">
<p class="text-sm text-gray-500 dark:text-gray-400 mb-4">{error}</p>
<button
class="text-sm text-primary hover:text-primary/80 transition-colors flex items-center justify-center gap-1"
onClick={() => fetchWeatherHotSearch()}
>
<Icon name="refresh" size="14" />
重试
</button>
</div>
{/if}

5. 添加到左侧边栏#

LeftSideBar.astro中引入新组件,并设置适当的动画延迟:

---
// 其他导入
import WeatherHotSearch from './WeatherHotSearch.astro';
---
<!-- 其他组件 -->
<WeatherHotSearch delay={0.4} />

🚀 测试和部署#

完成组件开发后,我启动了开发服务器进行测试:

Terminal window
pnpm run dev

开发服务器运行成功,组件显示正常,能够正确获取和展示天气热搜数据。

📝 总结#

本次实现的天气热搜卡片组件具有以下特点:

  1. 统一的设计风格:与博客现有组件保持一致的视觉风格
  2. 完整的状态管理:包含加载、成功和错误三种状态
  3. 良好的用户体验:提供骨架屏加载和错误重试功能
  4. 响应式设计:适配不同屏幕尺寸
  5. 可维护性:代码结构清晰,易于扩展和维护

这个组件为博客增加了实用的实时数据展示功能,提升了用户体验。

实现博客天气热搜卡片组件
https://blog.hoppinzq.com/posts/weather-hot-search-card-implementation/
作者
HOPPINZQ
发布于
2025-12-30
许可协议
CC BY-NC-SA 4.0

📝 记录笔记和心得 (0)

用户头像
游客
访客身份
加载笔记中...

AI助手

有问题随时问我

你好!我是HOPPINAI助手,有什么可以帮助你的吗?

你可能想:

刚刚

按 Enter 发送,Shift+Enter 换行

在线