Composition API简介
Vue 3的Composition API是Vue生态系统中最重要的革新之一。它提供了一种更灵活、更强大的方式来组织和复用组件逻辑。与传统的Options API相比,Composition API让代码更具可读性、可维护性和可测试性。
Options API vs Composition API
Options API(传统方式)
// Options API示例
export default {
data() {
return {
count: 0,
message: "Hello Vue!"
};
},
computed: {
doubledCount() {
return this.count * 2;
}
},
methods: {
increment() {
this.count++;
},
reset() {
this.count = 0;
}
},
mounted() {
console.log("组件已挂载");
}
};
Composition API(新方式)
// Composition API示例
import { ref, computed, onMounted } from "vue";
export default {
setup() {
// 响应式数据
const count = ref(0);
const message = ref("Hello Vue!");
// 计算属性
const doubledCount = computed(() => count.value * 2);
// 方法
const increment = () => {
count.value++;
};
const reset = () => {
count.value = 0;
};
// 生命周期钩子
onMounted(() => {
console.log("组件已挂载");
});
// 返回模板可用的数据和方法
return {
count,
message,
doubledCount,
increment,
reset
};
}
};
核心响应式API详解
1. ref – 创建响应式引用
import { ref } from "vue";
// 创建响应式引用
const count = ref(0);
const user = ref({ name: "张三", age: 25 });
// 访问值
console.log(count.value); // 0
console.log(user.value.name); // "张三"
// 修改值
count.value = 10;
user.value.age = 26;
2. reactive – 创建响应式对象
import { reactive } from "vue";
// 创建响应式对象
const state = reactive({
count: 0,
user: {
name: "李四",
profile: {
email: "lisi@example.com"
}
}
});
// 直接访问属性(无需.value)
console.log(state.count); // 0
console.log(state.user.profile.email); // "lisi@example.com"
// 修改属性
state.count = 5;
state.user.name = "王五";
3. computed – 计算属性
import { ref, computed } from "vue";
const price = ref(100);
const quantity = ref(2);
// 计算总价
const total = computed(() => price.value * quantity.value);
// 带getter和setter的计算属性
const fullName = computed({
get() {
return `${firstName.value} ${lastName.value}`;
},
set(newValue) {
const [first, last] = newValue.split(" ");
firstName.value = first;
lastName.value = last;
}
});
4. watch – 侦听器
import { ref, watch } from "vue";
const count = ref(0);
const user = ref({ name: "张三" });
// 侦听单个ref
watch(count, (newValue, oldValue) => {
console.log(`count从${oldValue}变为${newValue}`);
});
// 侦听多个源
watch([count, user], ([newCount, newUser], [oldCount, oldUser]) => {
console.log("count或user发生了变化");
});
// 深度侦听对象
watch(
user,
(newUser, oldUser) => {
console.log("user对象发生变化");
},
{ deep: true }
);
逻辑复用:Composable函数
创建可复用的逻辑
// 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 reset = () => count.value = initialValue;
const double = computed(() => count.value * 2);
return {
count,
increment,
decrement,
reset,
double
};
}
在组件中使用Composable
// Component.vue
import { useCounter } from "./useCounter";
export default {
setup() {
const { count, increment, reset, double } = useCounter(10);
return {
count,
increment,
reset,
double
};
}
};
实际应用:用户管理组件
// useUserManagement.js
import { ref, computed, watch } from "vue";
import { fetchUserData, updateUserProfile } from "./api";
export function useUserManagement(userId) {
const user = ref(null);
const loading = ref(false);
const error = ref(null);
// 计算属性
const isAdult = computed(() => {
return user.value?.age >= 18;
});
const fullName = computed(() => {
if (!user.value) return "";
return `${user.value.firstName} ${user.value.lastName}`;
});
// 方法
const loadUser = async () => {
loading.value = true;
error.value = null;
try {
user.value = await fetchUserData(userId);
} catch (err) {
error.value = err.message;
} finally {
loading.value = false;
}
};
const updateUser = async (updates) => {
try {
await updateUserProfile(userId, updates);
Object.assign(user.value, updates);
} catch (err) {
throw new Error(`更新失败: ${err.message}`);
}
};
// 自动加载用户数据
watch(() => userId, loadUser, { immediate: true });
return {
user,
loading,
error,
isAdult,
fullName,
loadUser,
updateUser
};
}
TypeScript支持
// 使用TypeScript的Composition API
import { ref, computed, Ref } from "vue";
interface User {
id: number;
name: string;
email: string;
age: number;
}
export function useUser() {
// 类型化的ref
const user: Ref = ref(null);
const loading = ref(false);
// 类型化的计算属性
const userName = computed(() => {
return user.value?.name || "未知用户";
});
const isAdult = computed(() => {
return user.value?.age >= 18;
});
return {
user,
loading,
userName,
isAdult
};
}
迁移策略
渐进式迁移
- 新组件使用Composition API:所有新开发的组件直接使用Composition API
- 复杂组件优先迁移:逻辑复杂的Options API组件优先迁移
- 提取可复用逻辑:将Options API中的逻辑提取为Composable函数
- 混合使用:在同一个项目中可以同时使用两种API
迁移工具
// 使用@vue/composition-api插件(Vue 2项目)
import Vue from "vue";
import VueCompositionAPI from "@vue/composition-api";
Vue.use(VueCompositionAPI);
// 在Vue 2组件中使用Composition API
export default {
setup() {
// Composition API代码
const count = ref(0);
return { count };
}
};
最佳实践
- 合理组织setup函数:按功能模块组织代码,避免setup函数过于臃肿
- 使用Composable提取逻辑:将相关逻辑提取为可复用的Composable函数
- 类型安全:使用TypeScript获得更好的类型支持和代码提示
- 性能优化:合理使用computed和watch,避免不必要的重新计算
- 错误处理:在异步操作中添加适当的错误处理机制
总结
Composition API代表了Vue框架的未来发展方向。虽然学习曲线比Options API稍陡,但它带来的代码组织灵活性、逻辑复用能力和TypeScript支持是无可替代的。对于新项目,建议直接使用Composition API;对于现有项目,可以采用渐进式迁移策略。掌握Composition API将使您能够构建更健壮、更易维护的Vue应用。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END




暂无评论内容