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