154 lines
3.7 KiB
Markdown
154 lines
3.7 KiB
Markdown
![]() |
# 重复变量声明问题修复说明
|
|||
|
|
|||
|
## 🐛 问题描述
|
|||
|
|
|||
|
在 `CourseDetailEnrolled.vue` 文件中出现了变量重复声明的编译错误:
|
|||
|
|
|||
|
```
|
|||
|
[vue/compiler-sfc] Identifier 'totalLessons' has already been declared. (69:6)
|
|||
|
```
|
|||
|
|
|||
|
## 🔍 问题原因
|
|||
|
|
|||
|
在同一个作用域中,`totalLessons` 被同时声明为 `ref` 和 `computed`:
|
|||
|
|
|||
|
```javascript
|
|||
|
// 第一次声明 - 作为 ref
|
|||
|
const totalLessons = ref(0)
|
|||
|
|
|||
|
// 第二次声明 - 作为 computed(导致冲突)
|
|||
|
const totalLessons = computed(() => {
|
|||
|
return groupedSections.value.length
|
|||
|
})
|
|||
|
```
|
|||
|
|
|||
|
## ✅ 修复方案
|
|||
|
|
|||
|
### 1. 移除重复的 ref 声明
|
|||
|
```javascript
|
|||
|
// 修复前
|
|||
|
const progress = ref(0)
|
|||
|
const completedLessons = ref(0)
|
|||
|
const totalLessons = ref(0) // ❌ 删除这行
|
|||
|
const totalSections = ref(0) // ❌ 删除这行
|
|||
|
|
|||
|
// 修复后
|
|||
|
const progress = ref(0)
|
|||
|
const completedLessons = ref(0)
|
|||
|
```
|
|||
|
|
|||
|
### 2. 保留 computed 声明
|
|||
|
```javascript
|
|||
|
// 保留这些 computed 声明
|
|||
|
const totalLessons = computed(() => {
|
|||
|
return groupedSections.value.length
|
|||
|
})
|
|||
|
|
|||
|
const totalSections = computed(() => {
|
|||
|
return courseSections.value.length
|
|||
|
})
|
|||
|
```
|
|||
|
|
|||
|
### 3. 修复相关使用
|
|||
|
```javascript
|
|||
|
// 修复前 - 错误地将 computed 当作 ref 使用
|
|||
|
totalSections.value = mockSections.length // ❌ 错误
|
|||
|
|
|||
|
// 修复后 - 移除这行代码,因为 computed 是只读的
|
|||
|
// totalSections 会自动根据 courseSections.value.length 计算
|
|||
|
```
|
|||
|
|
|||
|
## 🎯 修复结果
|
|||
|
|
|||
|
### 变量声明正确性
|
|||
|
- ✅ `totalLessons`:只声明为 `computed`
|
|||
|
- ✅ `totalSections`:只声明为 `computed`
|
|||
|
- ✅ `progress`:声明为 `ref`
|
|||
|
- ✅ `completedLessons`:声明为 `ref`
|
|||
|
|
|||
|
### 自动计算逻辑
|
|||
|
```javascript
|
|||
|
// totalLessons 自动计算章节数量
|
|||
|
const totalLessons = computed(() => {
|
|||
|
return groupedSections.value.length // 返回章节组数量
|
|||
|
})
|
|||
|
|
|||
|
// totalSections 自动计算课程总数
|
|||
|
const totalSections = computed(() => {
|
|||
|
return courseSections.value.length // 返回课程总数量
|
|||
|
})
|
|||
|
```
|
|||
|
|
|||
|
### 进度计算逻辑
|
|||
|
```javascript
|
|||
|
// 在 loadMockData 函数中
|
|||
|
const completed = mockSections.filter(section => section.completed).length
|
|||
|
completedLessons.value = completed // 更新已完成数量
|
|||
|
progress.value = Math.round((completed / mockSections.length) * 100) // 计算百分比
|
|||
|
|
|||
|
// totalSections 会自动更新,因为 courseSections.value 已更新
|
|||
|
```
|
|||
|
|
|||
|
## 🔧 技术说明
|
|||
|
|
|||
|
### Computed vs Ref 的区别
|
|||
|
```javascript
|
|||
|
// ref - 可读写的响应式变量
|
|||
|
const count = ref(0)
|
|||
|
count.value = 10 // ✅ 可以修改
|
|||
|
|
|||
|
// computed - 只读的计算属性
|
|||
|
const doubleCount = computed(() => count.value * 2)
|
|||
|
doubleCount.value = 20 // ❌ 错误!computed 是只读的
|
|||
|
```
|
|||
|
|
|||
|
### 正确的数据流
|
|||
|
```
|
|||
|
courseSections.value (ref)
|
|||
|
↓ 自动计算
|
|||
|
totalSections (computed)
|
|||
|
↓ 用于显示
|
|||
|
模板中的 {{ totalSections }}
|
|||
|
```
|
|||
|
|
|||
|
## ✅ 验证修复
|
|||
|
|
|||
|
### 1. 编译检查
|
|||
|
```bash
|
|||
|
# 应该没有编译错误
|
|||
|
npm run dev
|
|||
|
```
|
|||
|
|
|||
|
### 2. 功能验证
|
|||
|
- ✅ 页面可以正常加载
|
|||
|
- ✅ 章节数量正确显示
|
|||
|
- ✅ 学习进度正确计算
|
|||
|
- ✅ 所有计算属性正常工作
|
|||
|
|
|||
|
### 3. 控制台检查
|
|||
|
```javascript
|
|||
|
// 在浏览器控制台中应该看到
|
|||
|
console.log('模拟数据加载完成:', {
|
|||
|
total: mockSections.length, // 总课程数
|
|||
|
completed: completed, // 已完成数
|
|||
|
progress: progress.value // 进度百分比
|
|||
|
})
|
|||
|
```
|
|||
|
|
|||
|
## 🎉 修复完成
|
|||
|
|
|||
|
现在 `CourseDetailEnrolled.vue` 文件应该可以正常编译和运行,没有重复变量声明的错误。
|
|||
|
|
|||
|
### 页面访问路径
|
|||
|
- **未报名状态**:`http://localhost:5173/course/1`
|
|||
|
- **已报名状态**:`http://localhost:5173/course/1/enrolled`
|
|||
|
|
|||
|
### 测试流程
|
|||
|
1. 访问未报名状态页面
|
|||
|
2. 点击"立即报名"
|
|||
|
3. 确认报名
|
|||
|
4. 自动跳转到已报名状态页面
|
|||
|
5. 验证彩色可点击的课程章节
|
|||
|
|
|||
|
问题已完全解决!🚀
|