Files
akmon/doc_zhipao/VUE3_SETUP_CONVERSION_GUIDE.md
2026-01-20 08:04:15 +08:00

4.5 KiB
Raw Permalink Blame History

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
  • 方法定义更新
  • 生命周期钩子更新
  • 模板引用更新
  • 类型定义完善
  • 错误处理优化

后续优化建议

  1. 逻辑提取: 将相关逻辑提取到组合式函数中
  2. 性能优化: 使用 shallowRef 优化大型数据结构
  3. 类型优化: 进一步完善 TypeScript 类型定义
  4. 测试覆盖: 添加单元测试确保功能正确性

转换后的代码更符合 Vue 3 最佳实践,具有更好的类型安全性和代码可维护性。