你的浏览器无法正常显示内容,请更换或升级浏览器!

Vue 3 组合式 API 完全指南:从入门到实战

tenfei
tenfei
发布于2026-03-22 23:45 阅读9次
Vue 3 组合式 API 完全指南:从入门到实战
Vue 3 组合式 API 完全指南,详解 ref、reactive、computed、watch 等核心 API,介绍 Composables 逻辑复用方式,以及 TypeScript 集成和性能优化技巧。
# Vue 3 组合式 API 完全指南:从入门到实战 ## 前言 Vue 3 的发布带来了一个全新的编程范式——组合式 API(Composition API)。这不仅是 Vue 历史上最重要的更新之一,更是现代前端开发的一次重大变革。在本文中,我们将深入探讨组合式 API 的方方面面,帮助你从零基础到能够熟练运用这一强大工具。 ## 什么是组合式 API? 组合式 API 是 Vue 3 引入的一种新的组件编写方式,它允许我们使用函数式的 API 来组织组件逻辑。与传统的选项式 API(Options API)相比,组合式 API 提供了更好的逻辑复用能力、更灵活的代码组织方式,以及更清晰的类型推导支持。 ### 为什么需要组合式 API? 在大型项目中,我们经常会遇到一些问题: 1. **逻辑复用困难**:当多个组件需要使用相同的逻辑时,我们只能通过 mixins 来实现,但这会导致数据来源不清晰、命名冲突等问题。 2. **代码组织混乱**:随着组件功能增加,相关逻辑被迫分散在不同的选项中(data、methods、computed、watch 等),导致维护困难。 3. **类型推导不够友好**:尽管 Vue 2 已经支持 TypeScript,但选项式 API 的类型推导并不够完美。 组合式 API 正是为了解决这些问题而设计的。 ## 核心 API 详解 ### 1. ref 和 reactive `ref` 和 `reactive` 是组合式 API 中最基础的状态管理 API。 ```javascript import { ref, reactive } from "vue" // ref 用于创建基本类型的响应式数据 const count = ref(0) const message = ref("Hello Vue 3") // reactive 用于创建对象类型的响应式数据 const state = reactive({ name: "Vue", version: 3, features: ["Composition API", "Teleport", "Suspense"] }) // 在模板中使用时,ref 会自动解包 console.log(count.value) // 0 console.log(state.name) // Vue ``` **重要提示**:`ref` 创建的值需要通过 `.value` 属性来访问和修改,但在模板中会自动解包,无需使用 `.value`。 ### 2. computed 计算属性 ```javascript import { ref, computed } from "vue" const firstName = ref("John") const lastName = ref("Doe") // 创建计算属性 const fullName = computed(() => { return `${firstName.value} ${lastName.value}` }) // 计算属性也是响应式的 console.log(fullName.value) // "John Doe" ``` ### 3. watch 和 watchEffect ```javascript import { ref, watch, watchEffect } from "vue" const count = ref(0) // 监听特定数据变化 watch(count, (newValue, oldValue) => { console.log(`Count changed from ${oldValue} to ${newValue}`) }) // 立即执行,且自动收集依赖 const stop = watchEffect(() => { console.log(`Current count is: ${count.value}`) // 当 count 变化时,这个函数会自动重新执行 }) // 停止监听 stop() ``` ### 4. 生命周期钩子 组合式 API 中的生命周期钩子需要从 vue 中导入: ```javascript import { onMounted, onUpdated, onUnmounted, onBeforeMount, onBeforeUpdate, onBeforeUnmount } from "vue" onMounted(() => { console.log("Component mounted!") }) onBeforeMount(() => { console.log("Before mount") }) ``` ## 组件通信 ### 父子组件通信 ```javascript // ChildComponent.vue import { defineProps, defineEmits } from "vue" // 定义props const props = defineProps({ title: String, count: { type: Number, default: 0 } }) // 定义emit const emit = defineEmits(["update", "delete"]) const handleClick = () => { emit("update", "new value") } ``` ### 依赖注入 Provide/Inject ```javascript // 父组件 import { provide, ref } from "vue" const sharedData = ref("Shared data") provide("sharedKey", sharedData) // 子组件 import { inject } from "vue" const data = inject("sharedKey") console.log(data.value) // "Shared data" ``` ## 逻辑复用:Composables 组合式 API 最大的优势之一就是能够轻松实现逻辑复用。通过创建可复用的组合函数(Composables),我们可以将相关逻辑封装在一起。 ### 示例:鼠标位置追踪 ```javascript // useMouse.js import { ref, onMounted, onUnmounted } from "vue" export function useMouse() { const x = ref(0) const y = ref(0) const updateHandler = (event) => { x.value = event.pageX y.value = event.pageY } onMounted(() => { window.addEventListener("mousemove", updateHandler) }) onUnmounted(() => { window.removeEventListener("mousemove", updateHandler) }) return { x, y } } ``` ### 使用方式 ```javascript import { useMouse } from "./composables/useMouse" // 在组件中使用 const { x, y } = useMouse() console.log(`Mouse position: ${x.value}, ${y.value}`) ``` ### 更多实用示例 **useLocalStorage**:本地存储同步 ```javascript // useLocalStorage.js import { ref, watch } from "vue" export function useLocalStorage(key, defaultValue) { const data = ref(localStorage.getItem(key) || defaultValue) watch(data, (newValue) => { localStorage.setItem(key, newValue) }, { deep: true }) return data } ``` **useFetch**:数据获取 ```javascript // useFetch.js import { ref } from "vue" export function useFetch(url) { const data = ref(null) const loading = ref(true) const error = ref(null) fetch(url) .then(res => res.json()) .then(json => { data.value = json }) .catch(err => { error.value = err }) .finally(() => { loading.value = false }) return { data, loading, error } } ``` ## 高级特性 ### 1. Teleport 传送门 Teleport 允许我们将组件的模板部分渲染到 DOM 的任意位置: ```vue <template> <button @click="showModal = true">打开弹窗</button> <Teleport to="body"> <div v-if="showModal" class="modal"> <div class="content"> <p>这是一个模态框</p> <button @click="showModal = false">关闭</button> </div> </div> </Teleport> </template> ``` ### 2. Suspense 异步组件 Suspense 用于处理异步组件的加载状态: ```vue <template> <Suspense> <template #default> <AsyncComponent /> </template> <template #fallback> <Loading /> </template> </Suspense> </template> ``` ### 3. 片段 Fragment Vue 3 支持组件有多个根节点: ```vue <template> <header>Header content</header> <main>Main content</main> <footer>Footer content</footer> </template> ``` ## TypeScript 集成 组合式 API 对 TypeScript 提供了出色的支持: ```typescript import { ref, computed } from "vue" // 类型推导 const count = ref(0) // Type: Ref<number> const message = ref("hello") // Type: Ref<string> // 明确类型 const count2 = ref<number>(0) // 计算属性类型自动推导 const doubled = computed(() => count.value * 2) // 泛型函数 function useGeneric<T>(initialValue: T) { const data = ref<T>(initialValue) return { data } } const { data } = useGeneric<string>("Hello") ``` ## 性能优化 ### 1. 使用 shallowRef 对于大型对象,使用 `shallowRef` 可以避免深度响应式转换: ```javascript import { shallowRef, triggerRef } from "vue" // 只在顶层响应式,不会递归转换 const state = shallowRef({ deep: { nested: "value" } }) // 需要手动触发更新 triggerRef(state) ``` ### 2. readonly 保护数据 ```javascript import { readonly, reactive } from "vue" const original = reactive({ count: 0 }) // 创建只读副本 const copy = readonly(original) // 尝试修改会收到警告 // copy.count = 1 // 警告! ``` ## 迁移策略 从 Vue 2 迁移到 Vue 3 的组合式 API: 1. **渐进式迁移**:可以在同一个组件中混合使用选项式 API 和组合式 API 2. **逐步替换**:先将复杂的逻辑提取为 composables,再逐步改造组件 3. **保持兼容**:Vue 3 完全兼容 Vue 2 的选项式 API ## 最佳实践 1. **保持简洁**:每个 composable 应该有单一职责 2. **命名规范**:以 `use` 开头命名 composables 3. **返回值清晰**:返回必要的响应式引用,避免暴露不必要的内部状态 4. **避免响应式丢失**:不要在解构时丢失响应性 ```javascript // ❌ 错误:解构会丢失响应性 const { x, y } = useMouse() // ✅ 正确:保持响应性 const { x, y } = toRefs(useMouse()) // 或者 const mouse = useMouse() const { x, y } = toRefs(mouse) ``` ## 总结 Vue 3 的组合式 API 为我们带来了全新的组件开发体验。它不仅解决了长期困扰开发者的逻辑复用问题,还提供了更好的 TypeScript 支持和更灵活的代码组织方式。通过熟练掌握组合式 API,你将能够构建更加健壮、可维护的 Vue 应用程序。 组合式 API 是 Vue 3 最强大的特性之一,也是现代 Vue 开发的必备技能。希望本文能够帮助你更好地理解和应用这一强大工具。 --- **参考资料**: - Vue 3 官方文档 - Vue Composition API RFC - Vue 3 迁移指南

1

0

文章点评
暂无任何评论
Copyright © from 2021 by namoer.com
458815@qq.com QQ:458815
蜀ICP备2022020274号-2