uni-app 中 Composition API 和 Options API 的使用方法详解
一、Options API(Vue 2.x 传统方式)
1. 基本结构
Options API 通过配置对象的不同选项(如 data
、methods
、computed
等)组织代码:
<template>
<view>
<text>{{ count }}</text>
<button @click="increment">+1</button>
<text>{{ doubleCount }}</text>
</view>
</template>
<script>
export default {
// 数据
data() {
return {
count: 0,
name: 'uni-app'
};
},
// 计算属性
computed: {
doubleCount() {
return this.count * 2;
}
},
// 方法
methods: {
increment() {
this.count++;
}
},
// 生命周期钩子
onLoad() {
console.log('页面加载');
},
// 监听属性变化
watch: {
count(newVal, oldVal) {
console.log('count changed:', newVal, oldVal);
}
}
};
</script>
2. 特点
- 代码组织清晰:通过不同选项明确区分逻辑类型
- 学习成本低:适合 Vue 新手
- 与 uni-app 生命周期集成:如
onLoad
、onShow
等 - 组件通信:通过
props
、$emit
、$parent
等方式
3. 局限性
- 大型组件逻辑分散:相关功能(如表单验证)可能分散在不同选项中
- 代码复用困难:难以提取和复用跨组件的逻辑
- TypeScript 支持有限:类型推导不够直观
二、Composition API(Vue 3.0 新特性)
1. 基本结构
Composition API 通过 setup()
函数组织代码,使用 Vue 3.0 的响应式系统:
<template>
<view>
<text>{{ count }}</text>
<button @click="increment">+1</button>
<text>{{ doubleCount }}</text>
</view>
</template>
<script>
import { ref, computed, onMounted, watch } from 'vue';
export default {
setup() {
// 响应式数据
const count = ref(0);
const name = ref('uni-app');
// 计算属性
const doubleCount = computed(() => count.value * 2);
// 方法
const increment = () => {
count.value++;
};
// 生命周期钩子
onMounted(() => {
console.log('页面加载');
});
// 监听属性变化
watch(count, (newVal, oldVal) => {
console.log('count changed:', newVal, oldVal);
});
// 返回需要在模板中使用的数据和方法
return {
count,
name,
doubleCount,
increment
};
}
};
</script>
2. <script setup>
语法糖
更简洁的写法:
<template>
<view>
<text>{{ count }}</text>
<button @click="increment">+1</button>
<text>{{ doubleCount }}</text>
</view>
</template>
<script setup>
import { ref, computed, onMounted, watch } from 'vue';
// 响应式数据
const count = ref(0);
const name = ref('uni-app');
// 计算属性
const doubleCount = computed(() => count.value * 2);
// 方法
const increment = () => {
count.value++;
};
// 生命周期钩子
onMounted(() => {
console.log('页面加载');
});
// 监听属性变化
watch(count, (newVal, oldVal) => {
console.log('count changed:', newVal, oldVal);
});
</script>
3. 特点
- 逻辑集中:相关功能(如表单验证)可以组织在一起
- 代码复用性高:可以提取为组合函数(Composable Functions)
- 更好的 TypeScript 支持:类型推导更直观
- 与 uni-app 生命周期集成:如
onLoad
、onShow
等
4. 组合函数(Composable Functions)
提取可复用逻辑:
// useCounter.js
import { ref, computed } from 'vue';
export function useCounter(initialValue = 0) {
const count = ref(initialValue);
const increment = () => count.value++;
const decrement = () => count.value--;
const doubleCount = computed(() => count.value * 2);
return {
count,
increment,
decrement,
doubleCount
};
}
在组件中使用:
<template>
<view>
<text>{{ count }}</text>
<button @click="increment">+1</button>
<button @click="decrement">-1</button>
<text>{{ doubleCount }}</text>
</view>
</template>
<script setup>
import { useCounter } from './useCounter';
const { count, increment, decrement, doubleCount } = useCounter(5);
</script>
三、在 uni-app 中使用 Composition API 处理生命周期
Composition API 可以通过以下方式与 uni-app 生命周期集成:
import { onLoad, onShow, onReady, onHide, onUnload } from 'vue';
export default {
setup() {
// 页面加载时
onLoad(() => {
console.log('页面加载');
});
// 页面显示时
onShow(() => {
console.log('页面显示');
});
// 页面初次渲染完成时
onReady(() => {
console.log('页面初次渲染完成');
});
// 页面隐藏时
onHide(() => {
console.log('页面隐藏');
});
// 页面卸载时
onUnload(() => {
console.log('页面卸载');
});
return {};
}
};
四、响应式系统
1. ref
和 reactive
import { ref, reactive } from 'vue';
// ref 用于基本类型
const count = ref(0);
console.log(count.value); // 访问值
count.value++; // 修改值
// reactive 用于对象
const state = reactive({
name: 'uni-app',
age: 30
});
console.log(state.name); // 访问值
state.age++; // 修改值
2. computed
import { ref, computed } from 'vue';
const count = ref(0);
const doubleCount = computed(() => count.value * 2);
const message = computed({
get() {
return `Count is ${count.value}`;
},
set(newValue) {
count.value = parseInt(newValue);
}
});
3. watch
和 watchEffect
import { ref, watch, watchEffect } from 'vue';
const count = ref(0);
// 监听单个响应式值
watch(count, (newVal, oldVal) => {
console.log('count changed:', newVal, oldVal);
});
// 监听多个响应式值
watch([count, name], ([newCount, newName], [oldCount, oldName]) => {
console.log('values changed');
});
// 自动追踪依赖
watchEffect(() => {
console.log('count is:', count.value);
});
五、与 uni-app 特定 API 集成
1. 使用 uni-app API
import { ref, onLoad } from 'vue';
export default {
setup() {
const location = ref(null);
onLoad(() => {
uni.getLocation({
success: (res) => {
location.value = res;
}
});
});
return {
location
};
}
};
2. 自定义组合函数
// useLocation.js
import { ref, onLoad, onUnload } from 'vue';
export function useLocation() {
const location = ref(null);
const error = ref(null);
const getLocation = () => {
uni.getLocation({
success: (res) => {
location.value = res;
error.value = null;
},
fail: (err) => {
error.value = err;
}
});
};
onLoad(() => {
getLocation();
});
return {
location,
error,
getLocation
};
}
六、两种 API 的对比与选择
特性 | Options API | Composition API |
---|---|---|
代码组织 | 按选项(data、methods 等) | 按功能逻辑 |
逻辑复用 | 混入(Mixins)、高阶组件 | 组合函数(Composable) |
大型组件 | 逻辑分散 | 逻辑集中 |
TypeScript 支持 | 一般 | 优秀 |
学习曲线 | 平缓 | 较陡 |
与 Vue 2.x 兼容性 | 100% | 部分特性需适配 |
七、推荐使用方式
-
新项目:
- 优先使用 Composition API +
<script setup>
- 利用组合函数提高代码复用性
- 优先使用 Composition API +
-
现有项目:
- 逐步迁移到 Composition API
- 复杂组件优先迁移
- 保持两种 API 并存
-
注意事项:
- 熟悉 Vue 3.0 的响应式系统(ref、reactive)
- 正确处理 uni-app 生命周期
- 注意
ref
值的访问(需通过.value
)
总结
Composition API 是 Vue 3.0 的核心特性,在 uni-app 中使用可以提高代码的可维护性和复用性。对于大型项目或需要复杂逻辑复用的场景,推荐使用 Composition API;对于小型项目或初学者,可以继续使用 Options API。两种 API 可以在同一个项目中并存,开发者可以根据具体需求选择合适的方式。