Files
my-mom-system/.cursor/plans/修复layout菜单操作失效_99a7ebb5.plan.md
panchengyong c28ada5050 commit content
2026-03-06 02:02:59 +08:00

342 lines
8.9 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
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.
---
name: 修复Layout菜单操作失效
overview: 修复 Vue 2 到 Vue 3 迁移导致的 layout 菜单折叠/展开/关闭失效问题,根本原因是使用了 Vue 2 的 beforeDestroy 生命周期钩子,需要全部替换为 Vue 3 的 beforeUnmount
todos:
- id: fix-resize-handler
content: "修复 ResizeHandler.js: beforeDestroy → beforeUnmount"
status: completed
- id: fix-topnav
content: "修复 TopNav/index.vue: beforeDestroy → beforeUnmount"
status: completed
- id: fix-screenfull
content: "修复 Screenfull/index.vue: beforeDestroy → beforeUnmount"
status: completed
- id: fix-rightpanel
content: "修复 RightPanel/index.vue: beforeDestroy → beforeUnmount"
status: completed
- id: fix-editor-countto
content: "修复 Editor 和 CountTo 组件: beforeDestroy → beforeUnmount"
status: completed
- id: fix-chart-components
content: "修复所有图表组件和 mixins: beforeDestroy → beforeUnmount"
status: completed
- id: verify-layout
content: 验证侧边栏、顶部菜单、全屏、右侧面板功能
status: completed
isProject: false
---
# 修复 Layout 菜单操作失效问题
## 问题根源
Vue 3 中,生命周期钩子名称发生了变化:
- `beforeDestroy``beforeUnmount`
- `destroyed``unmounted`
当前项目使用了 `@vue/compat` (Vue 3 兼容模式),但这些组件仍在使用 Vue 2 的生命周期钩子。这导致组件销毁时的清理代码(移除事件监听器)没有执行,从而导致:
1. **侧边栏折叠/展开失效** - `[ResizeHandler.js](mom-backend-ui/src/layout/mixin/ResizeHandler.js)` 中的 resize 监听器没有正确清理
2. **顶部菜单操作失效** - `[TopNav/index.vue](mom-backend-ui/src/components/TopNav/index.vue)` 中的 resize 监听器问题
3. **右侧面板关闭失效** - `[RightPanel/index.vue](mom-backend-ui/src/components/RightPanel/index.vue)` 中的 click 监听器问题
4. **全屏功能失效** - `[Screenfull/index.vue](mom-backend-ui/src/components/Screenfull/index.vue)` 中的监听器问题
## 影响范围
共 13 个文件使用了 `beforeDestroy`
### 核心 Layout 相关(优先级 P0
1. `[src/layout/mixin/ResizeHandler.js](mom-backend-ui/src/layout/mixin/ResizeHandler.js)` - 控制侧边栏响应式
2. `[src/components/TopNav/index.vue](mom-backend-ui/src/components/TopNav/index.vue)` - 顶部菜单
3. `[src/components/Screenfull/index.vue](mom-backend-ui/src/components/Screenfull/index.vue)` - 全屏功能
4. `[src/components/RightPanel/index.vue](mom-backend-ui/src/components/RightPanel/index.vue)` - 右侧面板
### 其他组件(优先级 P1
1. `[src/components/Editor/index.vue](mom-backend-ui/src/components/Editor/index.vue)` - 富文本编辑器
2. `[src/components/CountTo/index.vue](mom-backend-ui/src/components/CountTo/index.vue)` - 数字动画
### 图表组件(优先级 P2
1. `src/views/dashboard/BarChart.vue`
2. `src/views/dashboard/LineChart.vue`
3. `src/views/dashboard/PieChart.vue`
4. `src/views/dashboard/RaddarChart.vue`
5. `src/views/mes/report/chart/chart.vue`
6. `src/views/mes/report/chart/mixins/resize.js`
7. `src/views/dashboard/mixins/resize.js`
## 修复方案
### 方案:批量替换生命周期钩子
所有文件中的 `beforeDestroy` 直接替换为 `beforeUnmount`
### 具体修改
#### 1. ResizeHandler Mixin
**文件**: `[src/layout/mixin/ResizeHandler.js](mom-backend-ui/src/layout/mixin/ResizeHandler.js)`
**第 17-19 行**:
```javascript
// 修复前
beforeDestroy() {
window.removeEventListener('resize', this.$_resizeHandler)
},
// 修复后
beforeUnmount() {
window.removeEventListener('resize', this.$_resizeHandler)
},
```
**影响**: 修复侧边栏折叠/展开功能
---
#### 2. TopNav 组件
**文件**: `[src/components/TopNav/index.vue](mom-backend-ui/src/components/TopNav/index.vue)`
**第 107-109 行**:
```javascript
// 修复前
beforeDestroy() {
window.removeEventListener('resize', this.setVisibleNumber)
},
// 修复后
beforeUnmount() {
window.removeEventListener('resize', this.setVisibleNumber)
},
```
**影响**: 修复顶部菜单响应式
---
#### 3. Screenfull 组件
**文件**: `[src/components/Screenfull/index.vue](mom-backend-ui/src/components/Screenfull/index.vue)`
**第 20-22 行**:
```javascript
// 修复前
beforeDestroy() {
this.destroy()
},
// 修复后
beforeUnmount() {
this.destroy()
},
```
**影响**: 修复全屏功能
---
#### 4. RightPanel 组件
**文件**: `[src/components/RightPanel/index.vue](mom-backend-ui/src/components/RightPanel/index.vue)`
**第 59-62 行**:
```javascript
// 修复前
beforeDestroy() {
const elx = this.$refs.rightPanel
elx.remove()
},
// 修复后
beforeUnmount() {
const elx = this.$refs.rightPanel
elx.remove()
},
```
**影响**: 修复右侧面板关闭功能
---
#### 5-6. Editor 和 CountTo 组件
**文件**:
- `src/components/Editor/index.vue`
- `src/components/CountTo/index.vue`
**修改**: `beforeDestroy``beforeUnmount`
---
#### 7-13. 图表组件和 Mixins
**文件**:
- `src/views/dashboard/BarChart.vue`
- `src/views/dashboard/LineChart.vue`
- `src/views/dashboard/PieChart.vue`
- `src/views/dashboard/RaddarChart.vue`
- `src/views/mes/report/chart/chart.vue`
- `src/views/mes/report/chart/mixins/resize.js`
- `src/views/dashboard/mixins/resize.js`
**修改**: `beforeDestroy``beforeUnmount`
**影响**: 修复图表组件的内存泄漏问题
## 验证方法
### 测试 1: 侧边栏折叠/展开
1. 打开系统
2. 点击左上角的 hamburger 图标(三条横线)
3. 验证侧边栏正常折叠/展开
4. 调整浏览器窗口大小
5. 验证侧边栏在移动端自动收起
**预期结果**: 所有操作正常响应
---
### 测试 2: 顶部菜单
1. 启用顶部菜单模式(在布局设置中)
2. 点击顶部菜单项
3. 验证菜单切换正常
4. 调整浏览器窗口大小
5. 验证菜单项自动折叠到"更多菜单"
**预期结果**: 菜单操作正常
---
### 测试 3: 全屏功能
1. 点击顶部工具栏的全屏图标
2. 验证进入全屏
3. 再次点击退出全屏
4. 验证图标状态正确切换
**预期结果**: 全屏功能正常
---
### 测试 4: 右侧面板
1. 点击顶部的"布局设置"
2. 验证右侧面板打开
3. 点击面板外部区域
4. 验证面板自动关闭
**预期结果**: 面板开关正常
---
### 测试 5: 控制台检查
打开浏览器控制台,执行以下检查:
1. 切换不同页面
2. 确认没有 "beforeDestroy is deprecated" 警告
3. 确认没有内存泄漏警告
4. 确认事件监听器正确添加和移除
## Vue 3 生命周期对照表
| Vue 2 | Vue 3 | 说明 |
| --------------- | --------------- | -------- |
| `beforeCreate` | `beforeCreate` | 无变化 |
| `created` | `created` | 无变化 |
| `beforeMount` | `beforeMount` | 无变化 |
| `mounted` | `mounted` | 无变化 |
| `beforeUpdate` | `beforeUpdate` | 无变化 |
| `updated` | `updated` | 无变化 |
| `beforeDestroy` | `beforeUnmount` | **已重命名** |
| `destroyed` | `unmounted` | **已重命名** |
| `activated` | `activated` | 无变化 |
| `deactivated` | `deactivated` | 无变化 |
| `errorCaptured` | `errorCaptured` | 无变化 |
## 技术要点
### 为什么需要修复
1. **事件监听器泄漏**: `beforeDestroy` 未执行导致 `removeEventListener` 没有调用
2. **内存泄漏**: 未清理的监听器持续占用内存
3. **功能失效**: 新的事件监听器无法正常工作
4. **Vue 3 兼容性**: `@vue/compat` 不完全支持 Vue 2 语法
### 影响分析
```mermaid
graph TD
A[组件挂载] --> B[添加事件监听器]
B --> C[组件使用中]
C --> D[组件卸载]
D --> E{生命周期钩子}
E -->|Vue 2: beforeDestroy| F[执行清理代码]
E -->|Vue 3: beforeUnmount| F
E -->|使用错误钩子| G[清理代码未执行]
G --> H[监听器未移除]
H --> I[功能失效]
H --> J[内存泄漏]
F --> K[监听器正确移除]
K --> L[功能正常]
```
## 修复优先级
### P0 - 立即修复(影响核心功能)
- ResizeHandler.js
- TopNav/index.vue
- Screenfull/index.vue
- RightPanel/index.vue
### P1 - 高优先级(影响用户体验)
- Editor/index.vue
- CountTo/index.vue
### P2 - 中优先级(影响特定页面)
- 所有图表组件和 mixins
## 预期效果
修复后:
- ✅ 侧边栏折叠/展开正常工作
- ✅ 顶部菜单响应式正常
- ✅ 全屏功能正常
- ✅ 右侧面板开关正常
- ✅ 无内存泄漏
- ✅ 无控制台警告
## 后续建议
1. **全局搜索其他 Vue 2 语法**:
```bash
grep -r "beforeDestroy\|destroyed\|\$listeners\|\$on\|\$off" --include="*.vue" --include="*.js"
```
2. **考虑完全迁移到 Vue 3**:
- 移除 `@vue/compat` 依赖
- 使用纯 Vue 3 API
- 更新所有组件库到最新版本
3. **添加 ESLint 规则**:
检测和阻止使用已弃用的 Vue 2 API