首页
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} />🚀 测试和部署
完成组件开发后,我启动了开发服务器进行测试:
pnpm run dev开发服务器运行成功,组件显示正常,能够正确获取和展示天气热搜数据。
📝 总结
本次实现的天气热搜卡片组件具有以下特点:
- 统一的设计风格:与博客现有组件保持一致的视觉风格
- 完整的状态管理:包含加载、成功和错误三种状态
- 良好的用户体验:提供骨架屏加载和错误重试功能
- 响应式设计:适配不同屏幕尺寸
- 可维护性:代码结构清晰,易于扩展和维护
这个组件为博客增加了实用的实时数据展示功能,提升了用户体验。
📝 记录笔记和心得 (0)
游客
访客身份
⏳
加载笔记中...