引言:Vue 3的革命性变化
Vue 3带来了许多令人兴奋的新特性,其中最引人注目的就是Composition API。这个新的API设计彻底改变了我们编写Vue组件的方式,提供了更好的代码组织、类型支持和逻辑复用能力。
1. Options API vs Composition API
首先,让我们对比一下传统的Options API和新的Composition API。
Options API(传统方式)
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
<p>Double: {{ doubleCount }}</p>
</div>
</template>
<script>
export default {
data() {
return {
count: 0
};
},
computed: {
doubleCount() {
return this.count * 2;
}
},
methods: {
increment() {
this.count++;
}
},
mounted() {
console.log("Component mounted");
}
};
</script>
Composition API(现代方式)
<template>
<div>
<p>Count: {{ count }}</p>
<button @click="increment">Increment</button>
<p>Double: {{ doubleCount }}</p>
</div>
</template>
<script setup>
import { ref, computed, onMounted } from "vue";
// 响应式状态
const count = ref(0);
// 计算属性
const doubleCount = computed(() => count.value * 2);
// 方法
function increment() {
count.value++;
}
// 生命周期钩子
onMounted(() => {
console.log("Component mounted");
});
</script>
2. Composition API核心概念
2.1 ref和reactive
ref和reactive是创建响应式数据的两种主要方式。
import { ref, reactive } from "vue";
// ref用于基本类型
const count = ref(0);
const message = ref("Hello Vue 3");
// reactive用于对象
const user = reactive({
name: "张三",
age: 25,
email: "zhangsan@example.com"
});
// 访问ref的值需要使用.value
console.log(count.value); // 0
count.value = 1; // 更新值
// reactive对象可以直接访问
console.log(user.name); // 张三
user.age = 26; // 直接更新
2.2 computed和watch
import { ref, computed, watch } from "vue";
const price = ref(100);
const quantity = ref(2);
// 计算属性
tconst total = computed(() => price.value * quantity.value);
// 监听器
watch(quantity, (newValue, oldValue) => {
console.log(`数量从 ${oldValue} 变为 ${newValue}`);
console.log(`新的总价: ${total.value}`);
});
// 监听多个源
watch([price, quantity], ([newPrice, newQuantity], [oldPrice, oldQuantity]) => {
console.log(`价格或数量发生变化`);
});
3. 逻辑复用:Composables
Composition API最大的优势之一是逻辑复用。我们可以创建可复用的composable函数。
// useCounter.js - 可复用的计数器逻辑
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
};
}
// 在组件中使用
<script setup>
import { useCounter } from "./useCounter";
const { count, increment, double } = useCounter(10);
</script>
4. 实际应用:用户管理组件
让我们创建一个实际的用户管理组件,展示Composition API的强大功能。
<template>
<div>
<h2>用户管理</h2>
<div v-if="loading">加载中...</div>
<div v-else>
<input
v-model="searchQuery"
placeholder="搜索用户"
@input="searchUsers"
/>
<ul>
<li v-for="user in filteredUsers" :key="user.id">
{{ user.name }} - {{ user.email }}
<button @click="() => selectUser(user)">选择</button>
</li>
</ul>
<div v-if="selectedUser">
<h3>已选择: {{ selectedUser.name }}</h3>
<button @click="clearSelection">清除选择</button>
</div>
</div>
</div>
</template>
<script setup>
import { ref, computed, onMounted } from "vue";
// 响应式状态
const users = ref([]);
const loading = ref(true);
const searchQuery = ref("");
const selectedUser = ref(null);
// 计算属性:过滤用户
const filteredUsers = computed(() => {
if (!searchQuery.value) return users.value;
return users.value.filter(user =>
user.name.toLowerCase().includes(searchQuery.value.toLowerCase()) ||
user.email.toLowerCase().includes(searchQuery.value.toLowerCase())
);
});
// 方法
async function fetchUsers() {
try {
loading.value = true;
// 模拟API调用
const response = await fetch("https://api.example.com/users");
users.value = await response.json();
} catch (error) {
console.error("获取用户失败:", error);
} finally {
loading.value = false;
}
}
function searchUsers() {
// 搜索逻辑已通过计算属性处理
console.log("搜索关键词:", searchQuery.value);
}
function selectUser(user) {
selectedUser.value = user;
}
function clearSelection() {
selectedUser.value = null;
}
// 生命周期钩子
onMounted(() => {
fetchUsers();
});
</script>
5. TypeScript支持
Composition API天生对TypeScript友好,提供了更好的类型推断和类型安全。
<script setup lang="ts">
import { ref, computed } from "vue";
// 定义接口
interface User {
id: number;
name: string;
email: string;
age?: number; // 可选属性
}
// 类型化的ref
const users = ref<User[]>([]);
const selectedUserId = ref<number | null>(null);
// 类型化的计算属性
const selectedUser = computed<User | undefined>(() => {
return users.value.find(user => user.id === selectedUserId.value);
});
// 类型化的函数
function addUser(user: User): void {
users.value.push(user);
}
// 自动类型推断
const count = ref(0); // 推断为Ref<number>
const message = ref("Hello"); // 推断为Ref<string>
</script>
6. 最佳实践
- 逻辑组织:将相关逻辑组织在一起,而不是按选项类型分散
- Composables:将可复用的逻辑提取到composable函数中
- 类型安全:使用TypeScript获得更好的开发体验
- 响应式优化:合理使用ref和reactive,避免不必要的响应式开销
- 代码拆分:大型组件可以拆分为多个composable函数
总结
Vue 3的Composition API代表了现代前端组件开发的未来方向。它提供了更好的代码组织、类型支持和逻辑复用能力。虽然Options API仍然可用且适合简单组件,但对于复杂应用和需要高度复用的场景,Composition API无疑是更好的选择。通过掌握Composition API,开发者可以编写更清晰、更可维护、更高效的Vue应用。
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END




暂无评论内容