Vue 3 Composition API实战:从Options到Composition的平滑迁移
随着Vue 3的普及,Composition API已经成为现代Vue开发的核心特性。与传统的Options API相比,Composition API提供了更好的代码组织、类型推断和逻辑复用能力。本文将带你从Options API平滑过渡到Composition API,并通过实际示例展示其优势。
1. Composition API基础概念
Composition API的核心是setup()函数,它在组件创建之前执行,接收props和context参数,并返回一个对象,该对象的属性将暴露给模板。
// Composition API 基础示例
import { ref, computed, onMounted } from 'vue';
export default {
props: {
initialCount: {
type: Number,
default: 0
}
},
setup(props) {
// 响应式数据
const count = ref(props.initialCount);
const doubleCount = computed(() => count.value * 2);
// 方法
const increment = () => {
count.value++;
};
// 生命周期钩子
onMounted(() => {
console.log('组件已挂载,当前计数:', count.value);
});
// 暴露给模板
return {
count,
doubleCount,
increment
};
}
};
2. 响应式系统对比
Composition API引入了更灵活的响应式系统:
// Options API 方式
export default {
data() {
return {
user: {
name: '张三',
age: 25
},
todos: []
};
},
computed: {
userNameUpperCase() {
return this.user.name.toUpperCase();
}
},
methods: {
addTodo(todo) {
this.todos.push(todo);
}
}
};
// Composition API 方式
import { reactive, ref, computed } from 'vue';
export default {
setup() {
// 对象使用 reactive
const user = reactive({
name: '张三',
age: 25
});
// 数组使用 ref
const todos = ref([]);
const userNameUpperCase = computed(() => {
return user.name.toUpperCase();
});
const addTodo = (todo) => {
todos.value.push(todo);
};
return {
user,
todos,
userNameUpperCase,
addTodo
};
}
};
3. 逻辑复用:Composables
Composition API最大的优势之一是逻辑复用。我们可以创建可复用的组合函数:
// useMouse.js - 鼠标位置跟踪
import { ref, onMounted, onUnmounted } from 'vue';
export function useMouse() {
const x = ref(0);
const y = ref(0);
const update = (event) => {
x.value = event.pageX;
y.value = event.pageY;
};
onMounted(() => window.addEventListener('mousemove', update));
onUnmounted(() => window.removeEventListener('mousemove', update));
return { x, y };
}
// useFetch.js - 数据获取
import { ref, onMounted } from 'vue';
export function useFetch(url) {
const data = ref(null);
const error = ref(null);
const loading = ref(false);
const fetchData = async () => {
loading.value = true;
try {
const response = await fetch(url);
data.value = await response.json();
} catch (err) {
error.value = err;
} finally {
loading.value = false;
}
};
onMounted(fetchData);
return {
data,
error,
loading,
refetch: fetchData
};
}
// 在组件中使用
import { useMouse, useFetch } from './composables';
export default {
setup() {
const { x, y } = useMouse();
const { data: posts, loading, error } = useFetch('https://api.example.com/posts');
return { x, y, posts, loading, error };
}
};
4. TypeScript支持
Composition API对TypeScript有更好的支持:
// 类型安全的Composition API
import { ref, computed, Ref } from 'vue';
interface User {
id: number;
name: string;
email: string;
}
interface Todo {
id: number;
title: string;
completed: boolean;
}
export default {
setup() {
// 明确类型声明
const user: Ref = ref(null);
const todos: Ref = ref([]);
const completedTodos = computed(() => {
return todos.value.filter(todo => todo.completed);
});
const addTodo = (title: string) => {
const newTodo: Todo = {
id: Date.now(),
title,
completed: false
};
todos.value.push(newTodo);
};
return {
user,
todos,
completedTodos,
addTodo
};
}
};
5. 迁移策略与最佳实践
从Options API迁移到Composition API的建议:
- 渐进式迁移:在新组件中使用Composition API,逐步改造旧组件
- 逻辑提取:将相关逻辑提取为Composables,提高复用性
- 类型优先:从一开始就使用TypeScript,享受更好的类型安全
- 工具支持:利用Vue DevTools的Composition API调试功能
// 混合使用示例(过渡期)
export default {
// Options API部分
data() {
return {
legacyData: '旧数据'
};
},
// Composition API部分
setup() {
const newData = ref('新数据');
const computedValue = computed(() => newData.value.toUpperCase());
return {
newData,
computedValue
};
},
// 两者都可以访问
mounted() {
console.log(this.legacyData); // 旧数据
console.log(this.newData); // 新数据
}
};
总结
Composition API代表了Vue开发的未来方向。虽然学习曲线比Options API稍陡,但它带来的代码组织、类型安全和逻辑复用优势是显著的。建议开发者从新项目开始就采用Composition API,并在现有项目中逐步迁移。
通过本文的示例,你应该已经掌握了Composition API的核心概念和实际应用。下一步可以探索更多高级特性,如watchEffect、provide/inject在Composition API中的使用,以及Vue 3生态中的新工具。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END




暂无评论内容