Initial commit of akmon project
This commit is contained in:
228
doc_zhipao/VUE3_SETUP_CONVERSION_GUIDE.md
Normal file
228
doc_zhipao/VUE3_SETUP_CONVERSION_GUIDE.md
Normal file
@@ -0,0 +1,228 @@
|
||||
# Vue 3 Setup 模式转换说明
|
||||
|
||||
## 概述
|
||||
|
||||
已成功将 `pages/sport/teacher/records.uvue` 从 Vue 2 Options API 转换为 Vue 3 Composition API (setup模式)。
|
||||
|
||||
## 主要变化
|
||||
|
||||
### 1. 脚本标签更改
|
||||
```vue
|
||||
<!-- 旧版本 -->
|
||||
<script lang="uts">
|
||||
export default {
|
||||
// Options API
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- 新版本 -->
|
||||
<script setup lang="uts">
|
||||
// Composition API
|
||||
</script>
|
||||
```
|
||||
|
||||
### 2. 导入语句
|
||||
```typescript
|
||||
// 新增 Vue 3 组合式 API 导入
|
||||
import { ref, computed, onMounted, nextTick } from 'vue'
|
||||
```
|
||||
|
||||
### 3. 数据定义转换
|
||||
|
||||
#### 旧版本 (Options API)
|
||||
```typescript
|
||||
data() {
|
||||
return {
|
||||
recordsRef: null,
|
||||
error: null,
|
||||
recordsLoading: false,
|
||||
allRecords: [],
|
||||
// ...其他状态
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 新版本 (Composition API)
|
||||
```typescript
|
||||
// 使用 ref 定义响应式数据
|
||||
const recordsRef = ref<SupadbComponentPublicInstance | null>(null)
|
||||
const error = ref<string | null>(null)
|
||||
const recordsLoading = ref(false)
|
||||
const allRecords = ref<UTSJSONObject[]>([])
|
||||
// ...其他状态
|
||||
```
|
||||
|
||||
### 4. 计算属性转换
|
||||
|
||||
#### 旧版本
|
||||
```typescript
|
||||
computed: {
|
||||
recordsFilter() {
|
||||
const filter = {}
|
||||
if (this.activeStatusFilter !== 'all') {
|
||||
filter.status = this.activeStatusFilter
|
||||
}
|
||||
return filter
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 新版本
|
||||
```typescript
|
||||
const recordsFilter = computed(() => {
|
||||
const filter: any = {}
|
||||
if (activeStatusFilter.value !== 'all') {
|
||||
filter.status = activeStatusFilter.value
|
||||
}
|
||||
return filter
|
||||
})
|
||||
```
|
||||
|
||||
### 5. 方法定义转换
|
||||
|
||||
#### 旧版本
|
||||
```typescript
|
||||
methods: {
|
||||
initializeDates() {
|
||||
const now = new Date()
|
||||
this.endDate = now.toISOString().split('T')[0]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 新版本
|
||||
```typescript
|
||||
const initializeDates = () => {
|
||||
const now = new Date()
|
||||
endDate.value = now.toISOString().split('T')[0]
|
||||
}
|
||||
```
|
||||
|
||||
### 6. 生命周期钩子转换
|
||||
|
||||
#### 旧版本
|
||||
```typescript
|
||||
onLoad() {
|
||||
this.initializeDates()
|
||||
},
|
||||
onReady() {
|
||||
this.recordsRef = this.$refs["recordsRef"]
|
||||
}
|
||||
```
|
||||
|
||||
#### 新版本
|
||||
```typescript
|
||||
onMounted(() => {
|
||||
initializeDates()
|
||||
nextTick(() => {
|
||||
recordsRef.value = uni.createSelectorQuery().select('#recordsRef')
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## 关键技术点
|
||||
|
||||
### 1. 响应式引用 (ref)
|
||||
- 基本数据类型使用 `ref()`
|
||||
- 对象和数组也使用 `ref()`
|
||||
- 访问值时需要 `.value`
|
||||
|
||||
### 2. 计算属性 (computed)
|
||||
- 使用 `computed()` 函数包装
|
||||
- 依赖的响应式数据自动追踪
|
||||
- 返回只读的响应式引用
|
||||
|
||||
### 3. 模板引用
|
||||
- 使用 `ref` 属性绑定到响应式引用
|
||||
- 通过 `.value` 访问 DOM 元素或组件实例
|
||||
|
||||
### 4. 事件处理
|
||||
- 方法定义为普通函数
|
||||
- 自动暴露给模板使用
|
||||
|
||||
### 5. 类型安全
|
||||
- 使用 TypeScript 泛型增强类型安全
|
||||
- 明确定义参数和返回值类型
|
||||
|
||||
## 优势
|
||||
|
||||
### 1. 更好的类型推导
|
||||
```typescript
|
||||
// 类型自动推导
|
||||
const count = ref(0) // Ref<number>
|
||||
const user = ref<User | null>(null) // Ref<User | null>
|
||||
```
|
||||
|
||||
### 2. 更好的代码组织
|
||||
- 相关逻辑可以组织在一起
|
||||
- 更容易提取和复用逻辑
|
||||
|
||||
### 3. 更好的树摇优化
|
||||
- 只导入使用的功能
|
||||
- 打包体积更小
|
||||
|
||||
### 4. 更好的 IDE 支持
|
||||
- 更准确的类型检查
|
||||
- 更好的自动补全
|
||||
|
||||
## 注意事项
|
||||
|
||||
### 1. 响应式访问
|
||||
```typescript
|
||||
// ❌ 错误:直接访问
|
||||
console.log(count)
|
||||
|
||||
// ✅ 正确:通过 .value 访问
|
||||
console.log(count.value)
|
||||
```
|
||||
|
||||
### 2. 模板中自动解包
|
||||
```vue
|
||||
<!-- 模板中自动解包,无需 .value -->
|
||||
<text>{{ count }}</text>
|
||||
<input v-model="searchQuery" />
|
||||
```
|
||||
|
||||
### 3. 解构赋值
|
||||
```typescript
|
||||
// ❌ 错误:会失去响应性
|
||||
const { count, name } = reactive({ count: 0, name: 'test' })
|
||||
|
||||
// ✅ 正确:使用 toRefs
|
||||
const { count, name } = toRefs(reactive({ count: 0, name: 'test' }))
|
||||
```
|
||||
|
||||
## 性能优化
|
||||
|
||||
### 1. 懒加载计算属性
|
||||
```typescript
|
||||
const expensiveComputed = computed(() => {
|
||||
// 只在依赖变化时重新计算
|
||||
return heavyCalculation(someReactiveData.value)
|
||||
})
|
||||
```
|
||||
|
||||
### 2. 条件性响应式
|
||||
```typescript
|
||||
const conditionalData = ref(null)
|
||||
// 只在需要时创建响应式数据
|
||||
```
|
||||
|
||||
## 迁移清单
|
||||
|
||||
- ✅ 数据属性转换为 ref/reactive
|
||||
- ✅ 计算属性转换为 computed
|
||||
- ✅ 方法定义更新
|
||||
- ✅ 生命周期钩子更新
|
||||
- ✅ 模板引用更新
|
||||
- ✅ 类型定义完善
|
||||
- ✅ 错误处理优化
|
||||
|
||||
## 后续优化建议
|
||||
|
||||
1. **逻辑提取**: 将相关逻辑提取到组合式函数中
|
||||
2. **性能优化**: 使用 `shallowRef` 优化大型数据结构
|
||||
3. **类型优化**: 进一步完善 TypeScript 类型定义
|
||||
4. **测试覆盖**: 添加单元测试确保功能正确性
|
||||
|
||||
转换后的代码更符合 Vue 3 最佳实践,具有更好的类型安全性和代码可维护性。
|
||||
Reference in New Issue
Block a user