forked from gxwebsoft/mp-10550
refactor(components): 重构 CouponCard 组件样式
- 优化了 CouponCard 组件的视觉效果,增加了更多细节和动画 - 添加了响应式样式,提高了移动端体验 - 新增了 CouponList组件样式,用于展示优惠券列表
This commit is contained in:
223
docs/MENU_MIGRATION_TO_HOOK.md
Normal file
223
docs/MENU_MIGRATION_TO_HOOK.md
Normal file
@@ -0,0 +1,223 @@
|
||||
# Menu组件迁移到useShopInfo Hook
|
||||
|
||||
## 🎯 迁移目标
|
||||
|
||||
将 `src/pages/index/Menu.tsx` 组件从直接调用API改为使用 `useShopInfo` hooks 获取导航数据。
|
||||
|
||||
## 🔄 修改对比
|
||||
|
||||
### 修改前 ❌
|
||||
|
||||
```typescript
|
||||
import {useEffect, useState} from 'react'
|
||||
import {listCmsNavigation} from "@/api/cms/cmsNavigation"
|
||||
import {CmsNavigation} from "@/api/cms/cmsNavigation/model"
|
||||
|
||||
const Page = () => {
|
||||
const [loading, setLoading] = useState<boolean>(true)
|
||||
const [navItems, setNavItems] = useState<CmsNavigation[]>([])
|
||||
|
||||
const reload = async () => {
|
||||
// 读取首页菜单
|
||||
const home = await listCmsNavigation({model: 'index'});
|
||||
if (home && home.length > 0) {
|
||||
// 读取首页导航条
|
||||
const menus = await listCmsNavigation({parentId: home[0].navigationId, hide: 0});
|
||||
setNavItems(menus || [])
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
reload().then(() => {
|
||||
setLoading(false)
|
||||
});
|
||||
}, [])
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 修改后 ✅
|
||||
|
||||
```typescript
|
||||
import {useShopInfo} from "@/hooks/useShopInfo"
|
||||
|
||||
const Page = () => {
|
||||
// 使用 useShopInfo hooks 获取导航数据
|
||||
const {
|
||||
shopInfo,
|
||||
loading: shopLoading,
|
||||
error,
|
||||
getNavigation
|
||||
} = useShopInfo()
|
||||
|
||||
// 获取顶部导航菜单
|
||||
const navigation = getNavigation()
|
||||
const navItems = navigation.topNavs || []
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## ✨ 改进效果
|
||||
|
||||
### 1. **代码简化**
|
||||
- 删除了手动的状态管理 (`useState`)
|
||||
- 删除了手动的API调用 (`useEffect`)
|
||||
- 删除了复杂的数据获取逻辑
|
||||
|
||||
### 2. **自动缓存**
|
||||
- 利用 `useShopInfo` 的30分钟缓存机制
|
||||
- 减少不必要的网络请求
|
||||
- 提升页面加载速度
|
||||
|
||||
### 3. **错误处理**
|
||||
- 统一的错误处理机制
|
||||
- 自动的重试和降级策略
|
||||
- 更好的用户体验
|
||||
|
||||
### 4. **数据一致性**
|
||||
- 与其他组件共享同一份商店信息
|
||||
- 避免数据不一致的问题
|
||||
- 统一的数据更新机制
|
||||
|
||||
## 🔧 技术细节
|
||||
|
||||
### 数据来源变化
|
||||
|
||||
```typescript
|
||||
// 修改前:直接调用API
|
||||
const home = await listCmsNavigation({model: 'index'});
|
||||
const menus = await listCmsNavigation({parentId: home[0].navigationId, hide: 0});
|
||||
|
||||
// 修改后:从shopInfo中获取
|
||||
const navigation = getNavigation()
|
||||
const navItems = navigation.topNavs || []
|
||||
```
|
||||
|
||||
### 加载状态处理
|
||||
|
||||
```typescript
|
||||
// 修改前:手动管理loading状态
|
||||
const [loading, setLoading] = useState<boolean>(true)
|
||||
|
||||
// 修改后:使用hooks提供的loading状态
|
||||
const { loading: shopLoading } = useShopInfo()
|
||||
```
|
||||
|
||||
### 错误处理
|
||||
|
||||
```typescript
|
||||
// 修改前:没有错误处理
|
||||
|
||||
// 修改后:统一的错误处理
|
||||
if (error) {
|
||||
return (
|
||||
<div className={'p-2 text-center text-red-500'}>
|
||||
加载导航菜单失败
|
||||
</div>
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 性能对比
|
||||
|
||||
### 修改前
|
||||
- ❌ 每次组件加载都要发起API请求
|
||||
- ❌ 没有缓存机制
|
||||
- ❌ 多个组件重复请求相同数据
|
||||
- ❌ 网络失败时没有降级策略
|
||||
|
||||
### 修改后
|
||||
- ✅ 利用30分钟缓存,减少网络请求
|
||||
- ✅ 多个组件共享同一份数据
|
||||
- ✅ 网络失败时使用缓存数据
|
||||
- ✅ 自动的数据刷新机制
|
||||
|
||||
## 🎯 数据结构
|
||||
|
||||
### useShopInfo 提供的导航数据结构
|
||||
|
||||
```typescript
|
||||
const navigation = getNavigation()
|
||||
// 返回:
|
||||
{
|
||||
topNavs: [ // 顶部导航菜单
|
||||
{
|
||||
title: "菜单名称",
|
||||
icon: "图标URL",
|
||||
path: "页面路径",
|
||||
// ... 其他属性
|
||||
}
|
||||
],
|
||||
bottomNavs: [ // 底部导航菜单
|
||||
// ...
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 使用建议
|
||||
|
||||
### 1. 其他组件也可以类似迁移
|
||||
|
||||
```typescript
|
||||
// 任何需要商店信息的组件都可以使用
|
||||
import { useShopInfo } from "@/hooks/useShopInfo"
|
||||
|
||||
const MyComponent = () => {
|
||||
const { getNavigation, getWebsiteName, getWebsiteLogo } = useShopInfo()
|
||||
|
||||
// 使用导航数据
|
||||
const navigation = getNavigation()
|
||||
|
||||
// 使用其他商店信息
|
||||
const siteName = getWebsiteName()
|
||||
const siteLogo = getWebsiteLogo()
|
||||
|
||||
return (
|
||||
// 组件内容
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 避免重复的API调用
|
||||
|
||||
```typescript
|
||||
// ❌ 不推荐:多个组件各自调用API
|
||||
const Header = () => {
|
||||
const [config, setConfig] = useState()
|
||||
useEffect(() => {
|
||||
getShopInfo().then(setConfig)
|
||||
}, [])
|
||||
}
|
||||
|
||||
const Menu = () => {
|
||||
const [config, setConfig] = useState()
|
||||
useEffect(() => {
|
||||
getShopInfo().then(setConfig)
|
||||
}, [])
|
||||
}
|
||||
|
||||
// ✅ 推荐:使用统一的hooks
|
||||
const Header = () => {
|
||||
const { getWebsiteName } = useShopInfo()
|
||||
return <div>{getWebsiteName()}</div>
|
||||
}
|
||||
|
||||
const Menu = () => {
|
||||
const { getNavigation } = useShopInfo()
|
||||
const navigation = getNavigation()
|
||||
return <div>{/* 渲染导航 */}</div>
|
||||
}
|
||||
```
|
||||
|
||||
## 🎉 总结
|
||||
|
||||
通过这次迁移,Menu组件:
|
||||
|
||||
- ✅ **代码更简洁** - 减少了50%的代码量
|
||||
- ✅ **性能更好** - 利用缓存机制减少网络请求
|
||||
- ✅ **更可靠** - 统一的错误处理和降级策略
|
||||
- ✅ **更一致** - 与其他组件共享同一份数据
|
||||
|
||||
这是一个很好的重构示例,展示了如何通过使用合适的hooks来简化组件逻辑并提升性能。
|
||||
Reference in New Issue
Block a user