在uni-app中如何从Options API迁移到Composition API?

uni-app 从 Options API 迁移到 Composition API 的详细指南

一、迁移前的准备
  1. 升级环境

    • 确保 HBuilderX 版本 ≥ 3.2.0
    • 项目 uni-app 版本 ≥ 3.0.0
  2. 了解 Composition API 基础

    • 响应式系统:refreactive
    • 生命周期钩子:onMountedonUnload
    • 组合函数:提取可复用逻辑
  3. 备份项目

    • 迁移前务必备份代码
    • 建议使用版本控制系统(如 Git)
二、渐进式迁移策略
  1. 组件级别迁移

    • 先迁移简单、独立的组件
    • 再处理复杂、依赖多的组件
  2. 功能模块迁移

    • 先迁移数据逻辑
    • 再迁移生命周期钩子
    • 最后处理计算属性和监听器
  3. 保持两种 API 并存

    • 迁移期间允许两种 API 在项目中共存
    • 新组件使用 Composition API,旧组件逐步迁移
三、基础语法迁移
1. 数据定义
javascript 复制代码
// Options API
export default {
  data() {
    return {
      count: 0,
      user: {
        name: 'John',
        age: 30
      }
    };
  }
}

// Composition API
import { ref, reactive } from 'vue';

export default {
  setup() {
    // 基本类型用 ref
    const count = ref(0);
    
    // 对象用 reactive
    const user = reactive({
      name: 'John',
      age: 30
    });
    
    return {
      count,
      user
    };
  }
}
2. 方法定义
javascript 复制代码
// Options API
export default {
  methods: {
    increment() {
      this.count++;
    }
  }
}

// Composition API
import { ref } from 'vue';

export default {
  setup() {
    const count = ref(0);
    
    const increment = () => {
      count.value++;
    };
    
    return {
      count,
      increment
    };
  }
}
3. 计算属性
javascript 复制代码
// Options API
export default {
  computed: {
    doubleCount() {
      return this.count * 2;
    }
  }
}

// Composition API
import { ref, computed } from 'vue';

export default {
  setup() {
    const count = ref(0);
    
    const doubleCount = computed(() => count.value * 2);
    
    return {
      count,
      doubleCount
    };
  }
}
4. 监听器
javascript 复制代码
// Options API
export default {
  watch: {
    count(newVal, oldVal) {
      console.log('count changed:', newVal, oldVal);
    }
  }
}

// Composition API
import { ref, watch } from 'vue';

export default {
  setup() {
    const count = ref(0);
    
    watch(count, (newVal, oldVal) => {
      console.log('count changed:', newVal, oldVal);
    });
    
    return {
      count
    };
  }
}
四、生命周期钩子迁移
javascript 复制代码
// Options API
export default {
  onLoad() {
    console.log('页面加载');
  },
  onShow() {
    console.log('页面显示');
  },
  onUnload() {
    console.log('页面卸载');
  }
}

// Composition API
import { onLoad, onShow, onUnload } from 'vue';

export default {
  setup() {
    onLoad(() => {
      console.log('页面加载');
    });
    
    onShow(() => {
      console.log('页面显示');
    });
    
    onUnload(() => {
      console.log('页面卸载');
    });
    
    return {};
  }
}
五、组合函数提取复用逻辑
javascript 复制代码
// Options API (mixins)
const counterMixin = {
  data() {
    return {
      count: 0
    };
  },
  methods: {
    increment() {
      this.count++;
    }
  }
};

export default {
  mixins: [counterMixin]
}

// Composition API (组合函数)
// useCounter.js
import { ref } from 'vue';

export function useCounter(initialValue = 0) {
  const count = ref(initialValue);
  
  const increment = () => {
    count.value++;
  };
  
  return {
    count,
    increment
  };
}

// 组件中使用
import { useCounter } from './useCounter';

export default {
  setup() {
    const { count, increment } = useCounter(5);
    
    return {
      count,
      increment
    };
  }
}
六、使用 <script setup> 简化语法
vue 复制代码
<template>
  <view>
    <text>{{ count }}</text>
    <button @click="increment">+1</button>
  </view>
</template>

<script setup>
import { ref, onLoad } from 'vue';

// 响应式数据
const count = ref(0);

// 方法
const increment = () => {
  count.value++;
};

// 生命周期钩子
onLoad(() => {
  console.log('页面加载');
});
</script>
七、处理组件通信
1. Props
javascript 复制代码
// Options API
export default {
  props: {
    message: String
  },
  methods: {
    handleClick() {
      console.log(this.message);
    }
  }
}

// Composition API
import { defineProps } from 'vue';

export default {
  props: {
    message: String
  },
  setup(props) {
    const handleClick = () => {
      console.log(props.message);
    };
    
    return {
      handleClick
    };
  }
}

// 或使用 <script setup>
<script setup>
const props = defineProps({
  message: String
});

const handleClick = () => {
  console.log(props.message);
};
</script>
2. Emits
javascript 复制代码
// Options API
export default {
  emits: ['update'],
  methods: {
    triggerUpdate() {
      this.$emit('update', 'new value');
    }
  }
}

// Composition API
import { defineEmits } from 'vue';

export default {
  emits: ['update'],
  setup(props, { emit }) {
    const triggerUpdate = () => {
      emit('update', 'new value');
    };
    
    return {
      triggerUpdate
    };
  }
}

// 或使用 <script setup>
<script setup>
const emit = defineEmits(['update']);

const triggerUpdate = () => {
  emit('update', 'new value');
};
</script>
八、处理特殊情况
1. 访问实例属性
javascript 复制代码
// Options API
export default {
  methods: {
    callMethod() {
      this.$refs.myRef.focus();
    }
  }
}

// Composition API
import { getCurrentInstance } from 'vue';

export default {
  setup() {
    const { proxy } = getCurrentInstance();
    
    const callMethod = () => {
      proxy.$refs.myRef.focus();
    };
    
    return {
      callMethod
    };
  }
}
2. 处理 ref
javascript 复制代码
// Options API
export default {
  mounted() {
    this.$refs.myRef.focus();
  }
}

// Composition API
import { ref, onMounted } from 'vue';

export default {
  setup() {
    const myRef = ref(null);
    
    onMounted(() => {
      myRef.value.focus();
    });
    
    return {
      myRef
    };
  }
}
九、测试与验证
  1. 单元测试

    • 确保迁移后的组件行为不变
    • 使用 Vue Test Utils 3.0+ 测试 Composition API
  2. 集成测试

    • 验证组件间交互正常
    • 测试路由、状态管理等集成功能
  3. 性能测试

    • 对比迁移前后的内存使用
    • 验证响应式系统性能
十、迁移建议
  1. 从简单组件开始

    • 先迁移无依赖的基础组件
    • 再迁移复杂业务组件
  2. 利用工具辅助

    • 使用 IDE 插件(如 Vetur)提供的代码转换功能
    • 参考 Vue 官方迁移工具
  3. 团队培训

    • 组织 Composition API 培训
    • 编写内部迁移指南和最佳实践
  4. 持续重构

    • 新功能优先使用 Composition API
    • 逐步重构旧组件

总结

从 Options API 迁移到 Composition API 是一个渐进的过程,需要耐心和规划。建议采用"组件级别迁移"和"功能模块迁移"相结合的策略,先易后难,逐步推进。在迁移过程中,充分利用 Composition API 的优势,如逻辑复用、更好的 TypeScript 支持等,提高代码质量和可维护性。

相关推荐
成都渲染101云渲染666620 小时前
如何在3ds Max中实现更快、更高质量的渲染
前端·javascript·人工智能
paopaokaka_luck1 天前
英语单词学习系统的设计与实现(基于艾宾浩斯遗忘曲线的智能复习机制、语音朗读、多题型测试与错题自动收录、Echarts图形化分析)
vue.js·spring boot·后端·echarts
SRET1 天前
Mineradio 沙盒隔离安装完全指南 | 一键安全运行 Electron 应用!!!
javascript·经验分享·安全·electron·aigc·音视频·ai编程
全栈前端老曹1 天前
【MongoDB】安全与权限管理 —— 用户认证、角色权限、SSL 加密
前端·javascript·数据库·安全·mongodb·nosql·ssl
free351 天前
作用域链与 Environment:变量查找、遮蔽和赋值怎么实现
javascript
Momo__1 天前
Vite 8.1 打包开发模式——10000 组件冷启动 15 倍,"No Bundle Dev" 七年后被自己终结
前端·vue.js·vite
YHL1 天前
🤖 Agent 智能体开发实战 · 第一课:Tool Use —— 让大模型自动干活
前端·javascript·人工智能
HUMHSX1 天前
Vue 组件通信核心知识点梳理
javascript·vue.js·ecmascript
风止何安啊1 天前
🚦 前端并发请求 “交通管制”:别让你的接口堵成早高峰
前端·javascript·面试
妙码生花1 天前
从 PHP 到 AI + Golang,程序员自救转型手记(二十六):icon 组件封装
前端·vue.js·typescript