
Vue 3组合式API改变了组件开发方式
Vue 3的组合式API(Composition API)彻底改变了我们构建组件的方式,提供了更灵活、更强大的代码组织能力。 相比传统的选项式API,组合式API通过逻辑复用、更好的类型推导和更灵活的组织方式, 让大型应用开发变得更加高效。本文将深入探讨组合式API的核心概念,并通过实战案例展示如何在实际项目中应用这些技术。
组合式API基础
组合式API的核心是setup()
函数,它是使用组合式API的入口点。在setup()
中,我们可以声明响应式状态、计算属性、方法等,并将它们返回给模板使用。
import { ref, computed } from 'vue';
export default {
setup() {
// 声明响应式状态
const count = ref(0);
// 声明计算属性
const doubled = computed(() => count.value * 2);
// 声明方法
const increment = () => {
count.value++;
};
// 返回模板可用的数据和方法
return {
count,
doubled,
increment
};
}
};
export default {
setup() {
// 声明响应式状态
const count = ref(0);
// 声明计算属性
const doubled = computed(() => count.value * 2);
// 声明方法
const increment = () => {
count.value++;
};
// 返回模板可用的数据和方法
return {
count,
doubled,
increment
};
}
};
为什么使用组合式API?
- 更好的逻辑复用 - 通过组合函数提取和复用逻辑
- 更灵活的代码组织 - 按功能而非选项类型组织代码
- 更好的类型推导 - 对TypeScript支持更友好
- 更小的打包体积 - 按需导入API函数
- 更好的性能 - 减少不必要的响应式追踪
响应式系统深入
Vue 3使用Proxy重写了响应式系统,提供了更强大的能力。核心响应式API包括:
ref()
基本类型响应式
用于创建基本类型的响应式引用
通过.value访问值
reactive()
对象响应式
创建对象的响应式代理
直接访问属性
computed()
计算属性
基于响应式数据派生值
惰性求值,自动追踪依赖
watch()
侦听器
响应数据变化执行副作用
可侦听多个源
import { ref, reactive, computed, watch } from 'vue';
export default {
setup() {
const count = ref(0);
const user = reactive({
name: '张三',
age: 25
});
const nextYearAge = computed(() => user.age + 1);
watch(count, (newVal, oldVal) => {
console.log(`count从${oldVal}变为${newVal}`);
});
return { count, user, nextYearAge };
}
};
export default {
setup() {
const count = ref(0);
const user = reactive({
name: '张三',
age: 25
});
const nextYearAge = computed(() => user.age + 1);
watch(count, (newVal, oldVal) => {
console.log(`count从${oldVal}变为${newVal}`);
});
return { count, user, nextYearAge };
}
};
组合函数实战
组合函数(Composables)是组合式API的精髓,它允许我们提取和复用状态逻辑。
1. 计数器组合函数
创建一个可复用的计数器逻辑:
// useCounter.js
import { ref } from 'vue';
export default function useCounter(initialValue = 0) {
const count = ref(initialValue);
const increment = () => count.value++;
const decrement = () => count.value--;
const reset = () => count.value = initialValue;
return {
count,
increment,
decrement,
reset
};
}
import { ref } from 'vue';
export default function useCounter(initialValue = 0) {
const count = ref(initialValue);
const increment = () => count.value++;
const decrement = () => count.value--;
const reset = () => count.value = initialValue;
return {
count,
increment,
decrement,
reset
};
}
2. 在组件中使用
import useCounter from './useCounter';
export default {
setup() {
const { count, increment, decrement, reset } = useCounter(10);
return {
count,
increment,
decrement,
reset
};
}
};
export default {
setup() {
const { count, increment, decrement, reset } = useCounter(10);
return {
count,
increment,
decrement,
reset
};
}
};
计数器组合函数演示
0
这个演示展示了组合函数在实际应用中的效果
生命周期钩子
在组合式API中,生命周期钩子以onX形式导入并使用:
onMounted()
组件挂载完成后调用
onUpdated()
组件更新后调用
onUnmounted()
组件卸载后调用
onBeforeMount()
组件挂载前调用
import { onMounted, onUnmounted } from 'vue';
export default {
setup() {
const fetchData = async () => {
// 获取数据逻辑
};
const handleResize = () => {
console.log('窗口大小改变');
};
// 组件挂载后获取数据
onMounted(() => {
fetchData();
window.addEventListener('resize', handleResize);
});
// 组件卸载前清理
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
});
}
};
export default {
setup() {
const fetchData = async () => {
// 获取数据逻辑
};
const handleResize = () => {
console.log('窗口大小改变');
};
// 组件挂载后获取数据
onMounted(() => {
fetchData();
window.addEventListener('resize', handleResize);
});
// 组件卸载前清理
onUnmounted(() => {
window.removeEventListener('resize', handleResize);
});
}
};
最佳实践
组合函数命名
组合函数应以"use"开头,如useUser、useFetch等,遵循约定提高可读性
逻辑分离
将相关逻辑组织在一起,而不是分散在不同选项中,提高可维护性
单一职责
每个组合函数应专注于单一功能,保持简洁和可复用性
返回对象解构
从组合函数返回对象而不是数组,允许按名称解构,提高可读性
注意事项
在组合函数中避免直接修改props,应使用emit触发事件。同时注意响应式对象在解构时会失去响应性,应使用toRefs保持响应性。