在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 支持等,提高代码质量和可维护性。

相关推荐
你的人类朋友10 分钟前
✍️Node.js CMS框架概述:Directus与Strapi详解
javascript·后端·node.js
啊~哈18 分钟前
vue3+elementplus表格表头加图标及文字提示
前端·javascript·vue.js
xiaogg367825 分钟前
vue+elementui 网站首页顶部菜单上下布局
javascript·vue.js·elementui
weixin_5275504033 分钟前
初级程序员入门指南
javascript·python·算法
HelloWord~1 小时前
SpringSecurity+vue通用权限系统
vue.js·spring boot
钡铼技术ARM工业边缘计算机1 小时前
千元级PLC平台支持梯形图+Python双开发
javascript
高山我梦口香糖2 小时前
[electron]预脚本不显示内联script
前端·javascript·electron
神探小白牙2 小时前
vue-video-player视频保活成功确无法推送问题
前端·vue.js·音视频
moxiaoran57532 小时前
uni-app学习笔记三十--request网络请求传参
笔记·学习·uni-app
Angel_girl3192 小时前
vue项目使用svg图标
前端·vue.js