Files
mini-programs/_doc/GUIDEBAR_UNIFIED_CONTROL.md
张成 dcbcbb49f6 1
2025-11-25 11:23:25 +08:00

380 lines
9.2 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GuideBar 统一控制实现总结
## ✅ 已完成的统一改造
所有页面和组件现在都使用 **`global store`** 统一管理 `GuideBar` 的显示与隐藏。
---
## 📦 核心实现
### 1. **Global Store** (`src/store/global.ts`)
```typescript
interface GlobalState {
showGuideBar: boolean;
guideBarZIndex: 'low' | 'high';
}
interface GlobalActions {
setShowGuideBar: (show: boolean) => void;
setGuideBarZIndex: (zIndex: 'low' | 'high') => void;
toggleGuideBar: () => void;
}
// 使用方法
import { useGlobalState } from "@/store/global";
const { showGuideBar, setShowGuideBar } = useGlobalState();
```
---
## 🎯 已改造的组件
### 1⃣ **LocationConfirmDialog** - 定位确认弹窗
**文件:** `src/components/LocationConfirmDialog/index.tsx`
**改造内容:**
- 使用 `useEffect` 监听 `visible` 状态
- `visible = true` 时自动隐藏 GuideBar
- `visible = false` 时自动显示 GuideBar
```typescript
const { setShowGuideBar } = useGlobalState();
useEffect(() => {
if (visible) {
setShowGuideBar(false); // 弹窗显示时隐藏
} else {
setShowGuideBar(true); // 弹窗关闭时显示
}
}, [visible, setShowGuideBar]);
```
**使用场景:**
- 用户首次打开应用时的定位确认
- 检测到位置变化时的切换提示
---
### 2⃣ **HomeNavbar** - 首页导航栏
**文件:** `src/components/HomeNavbar/index.tsx`
**改造内容:**
- 引入 `setShowGuideBar` 方法
- 在显示定位弹窗时调用隐藏
- 在确认/取消时调用显示
```typescript
const { setShowGuideBar } = useGlobalState();
const showLocationConfirmDialog = () => {
setShowGuideBar(false);
// ...
};
const handleLocationDialogConfirm = () => {
// ...
setShowGuideBar(true);
};
const handleLocationDialogCancel = () => {
// ...
setShowGuideBar(true);
};
```
**使用场景:**
- 城市切换提示
- 定位权限请求
---
### 3⃣ **UserInfo** - 用户信息组件(✨ 重要改造)
**文件:** `src/components/UserInfo/index.tsx`
**改造内容:**
- ❌ 移除 `FamilyContext` 依赖
- ✅ 改用 `useGlobalState` 统一管理
- 优化了所有选择器性别、地区、NTRP、职业的 GuideBar 控制逻辑
**之前(使用 Context**
```typescript
const { handleGrandchildTrigger } = useContext(FamilyContext);
handleGrandchildTrigger(true); // 隐藏(逻辑反转)
handleGrandchildTrigger(false); // 显示
```
**现在(使用 Store**
```typescript
const { setShowGuideBar } = useGlobalState();
setShowGuideBar(false); // 隐藏(直观明了)
setShowGuideBar(true); // 显示
```
**具体改动:**
1. **打开编辑弹窗时隐藏 GuideBar**
```typescript
const handle_open_edit_modal = (field: string) => {
setShowGuideBar(false); // 之前: handleGrandchildTrigger(true)
// ...
};
```
2. **关闭编辑弹窗时显示 GuideBar**
```typescript
const handle_edit_modal_cancel = () => {
setShowGuideBar(true); // 之前: handleGrandchildTrigger(false)
// ...
};
```
3. **选择器状态联动**
```typescript
useEffect(() => {
const visibles = [
gender_picker_visible,
location_picker_visible,
ntrp_picker_visible,
occupation_picker_visible,
];
const allPickersClosed = visibles.every((item) => !item);
// 所有选择器都关闭时显示 GuideBar否则隐藏
setShowGuideBar(allPickersClosed);
}, [
gender_picker_visible,
location_picker_visible,
ntrp_picker_visible,
occupation_picker_visible,
]);
```
**使用场景:**
- "我的"页面编辑个人信息
- 性别选择器
- 地区选择器
- NTRP 等级选择器
- 职业选择器
- 昵称/简介编辑
---
### 4⃣ **MainPage** - 主页面容器
**文件:** `src/main_pages/index.tsx`
**改造内容:**
- 从 store 获取 `showGuideBar``setShowGuideBar`
- 保留 `handleGrandchildTrigger` 以保持向后兼容(但已无实际使用)
```typescript
const { showGuideBar, guideBarZIndex, setShowGuideBar, setGuideBarZIndex } = useGlobalState();
// 根据状态渲染 GuideBar
{
showGuideBar ?
<GuideBar
currentPage={currentTab}
guideBarClassName={guideBarZIndex === 'low' ? 'guide-bar-low-z-index' : 'guide-bar-high-z-index'}
onTabChange={handleTabChange}
onPublishMenuVisibleChange={handlePublishMenuVisibleChange}
/> :
null
}
```
---
## 🔄 工作流程
### 示例:用户编辑个人信息
1. **用户点击"编辑"按钮**
```
handle_open_edit_modal() 调用
→ setShowGuideBar(false)
→ GuideBar 隐藏
```
2. **用户打开性别选择器**
```
setGenderPickerVisible(true)
→ useEffect 检测到 visibles 变化
→ setShowGuideBar(false)
→ GuideBar 保持隐藏
```
3. **用户关闭选择器**
```
setGenderPickerVisible(false)
→ useEffect 检测到所有选择器都关闭
→ setShowGuideBar(true)
→ GuideBar 显示
```
4. **用户点击"取消"**
```
handle_edit_modal_cancel() 调用
→ setShowGuideBar(true)
→ GuideBar 显示
```
---
## 📊 对比表
| 项目 | 之前FamilyContext | 现在Global Store |
|------|---------------------|---------------------|
| **状态管理** | Context API跨层传递 | Zustand Store全局统一 |
| **调用方式** | `handleGrandchildTrigger(value)` | `setShowGuideBar(show)` |
| **逻辑清晰度** | ❌ 反转逻辑true=隐藏) | ✅ 直观逻辑false=隐藏) |
| **依赖关系** | ❌ 需要 Context Provider | ✅ 直接引入 hook |
| **类型安全** | ⚠️ `any` 类型 | ✅ 完整 TypeScript 类型 |
| **调试能力** | ❌ 难以追踪状态变化 | ✅ 集中日志,易于调试 |
| **可维护性** | ⚠️ 分散在多处 | ✅ 统一管理 |
| **性能** | ⚠️ Context 更新触发重渲染 | ✅ Zustand 精确订阅 |
---
## 🎨 优势
### 1. **代码更简洁**
```typescript
// 之前
const { handleGrandchildTrigger } = useContext(FamilyContext);
handleGrandchildTrigger(true); // 反直觉
// 现在
const { setShowGuideBar } = useGlobalState();
setShowGuideBar(false); // 直观明了
```
### 2. **逻辑更清晰**
- `setShowGuideBar(true)` → 显示 GuideBar
- `setShowGuideBar(false)` → 隐藏 GuideBar
- 不需要记忆反转逻辑
### 3. **调试更方便**
所有状态变化都有日志:
```
[UserInfo] 打开编辑弹窗,隐藏 GuideBar
[Store] setShowGuideBar called with: false
[Store] showGuideBar updated to: false
```
### 4. **类型安全**
```typescript
// 完整的 TypeScript 类型定义
interface GlobalActions {
setShowGuideBar: (show: boolean) => void; // ✅ 明确的参数类型
toggleGuideBar: () => void;
}
```
### 5. **易于扩展**
需要新功能时,只需在 store 中添加:
```typescript
// 未来可以轻松添加更多控制方法
interface GlobalActions {
setShowGuideBar: (show: boolean) => void;
setGuideBarZIndex: (zIndex: 'low' | 'high') => void;
toggleGuideBar: () => void;
hideGuideBarTemporarily: (duration: number) => void; // 新功能
}
```
---
## 📝 使用指南
### 在任何组件中使用
```typescript
import { useGlobalState } from "@/store/global";
function YourComponent() {
const { showGuideBar, setShowGuideBar, toggleGuideBar } = useGlobalState();
// 隐藏 GuideBar
const hideGuideBar = () => setShowGuideBar(false);
// 显示 GuideBar
const showGuideBar = () => setShowGuideBar(true);
// 切换显示/隐藏
const toggle = () => toggleGuideBar();
return <View>...</View>;
}
```
### 自动控制(推荐)
使用 `useEffect` 监听状态变化:
```typescript
useEffect(() => {
if (modalVisible) {
setShowGuideBar(false);
} else {
setShowGuideBar(true);
}
}, [modalVisible, setShowGuideBar]);
```
---
## ✅ 测试清单
### 定位弹窗测试
- [ ] 首次打开应用时定位弹窗显示GuideBar 隐藏
- [ ] 点击"切换到XX"弹窗关闭GuideBar 显示
- [ ] 点击"继续浏览XX"弹窗关闭GuideBar 显示
### 用户信息编辑测试
- [ ] 点击"编辑"按钮编辑弹窗显示GuideBar 隐藏
- [ ] 打开性别选择器GuideBar 保持隐藏
- [ ] 关闭性别选择器GuideBar 显示
- [ ] 打开地区选择器GuideBar 隐藏
- [ ] 关闭地区选择器GuideBar 显示
- [ ] 打开 NTRP 选择器GuideBar 隐藏
- [ ] 关闭 NTRP 选择器GuideBar 显示
- [ ] 点击"取消"编辑弹窗关闭GuideBar 显示
### 多选择器联动测试
- [ ] 同时打开多个选择器时GuideBar 保持隐藏
- [ ] 只有所有选择器都关闭时GuideBar 才显示
---
## 🔍 调试方法
### 查看控制台日志
```
[UserInfo] 打开编辑弹窗,隐藏 GuideBar
[Store] setShowGuideBar called with: false
[Store] showGuideBar updated to: false
[UserInfo] 关闭编辑弹窗,显示 GuideBar
[Store] setShowGuideBar called with: true
[Store] showGuideBar updated to: true
```
### React DevTools
1. 打开 React DevTools
2. 找到 `MainPage` 组件
3. 查看 `showGuideBar` 的实时值
4. 观察状态变化是否符合预期
---
## 🎉 总结
✅ **LocationConfirmDialog** - 使用 store 统一控制
✅ **HomeNavbar** - 使用 store 统一控制
✅ **UserInfo** - 已从 FamilyContext 迁移到 store
✅ **MainPage** - 使用 store 统一渲染
所有组件现在都通过 **`useGlobalState`** 统一管理 GuideBar代码更简洁、逻辑更清晰、维护更容易🚀