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

Vue 3 Composition API 实战:构建可复用的业务逻辑

tenfei
tenfei
发布于2026-03-30 00:18 阅读14次
Vue 3 Composition API 实战:构建可复用的业务逻辑
本文通过实际业务场景,深入讲解Vue 3 Composition API的核心用法,包括响应式数据管理、自定义Hook封装、依赖注入等,帮助开发者从Options API平滑过渡到Composition API,提升代码复用性和可维护性。
## Vue 3 Composition API 实战:构建可复用的业务逻辑 Vue 3 引入的 Composition API 是框架历史上最重大的变革之一。与传统的 Options API 相比,Composition API 提供了更灵活的代码组织方式,让开发者能够按逻辑关注点组织代码,而非被迫按选项类型分散到不同的配置块中。本文将从实际业务场景出发,带你掌握 Composition API 的核心用法。 ### 为什么选择 Composition API 在复杂业务组件中,Options API 的弊端显而易见。一个用户管理组件可能包含用户列表查询、表单验证、权限控制等多种逻辑,这些逻辑分散在 data、methods、computed、watch 等多个选项中,阅读和维护时需要反复跳转。Composition API 允许我们将相关逻辑聚合在一起,形成独立的、可复用的功能单元。 ### 响应式数据:ref 与 reactive Composition API 提供了两种创建响应式数据的方式:ref 和 reactive。ref 适用于基础类型和需要重新赋值的对象,reactive 则适用于对象结构稳定的场景。 ```javascript import { ref, reactive } from 'vue' // 使用 ref 管理基础类型 const searchKeyword = ref('') const currentPage = ref(1) const pageSize = ref(10) // 使用 reactive 管理复杂对象 const formState = reactive({ username: '', email: '', role: 'user', status: true }) ``` 需要注意的是,在模板中 ref 会自动解包,但在 JavaScript 中需要通过 .value 访问。reactive 则可以直接访问属性,但不能整体替换对象。 ### 计算属性与侦听器 computed 用于派生状态,watch 和 watchEffect 用于响应数据变化执行副作用。 ```javascript import { computed, watch, watchEffect } from 'vue' // 过滤后的用户列表 const filteredUsers = computed(() => { return users.value.filter(user => user.name.includes(searchKeyword.value) ) }) // 监听搜索关键词变化,重置分页 watch(searchKeyword, () => { currentPage.value = 1 fetchUsers() }) // 自动追踪依赖的副作用 watchEffect(() => { document.title = `用户管理 - 第 ${currentPage.value} 页` }) ``` watch 与 watchEffect 的区别在于:watch 需要明确指定监听源,而 watchEffect 会自动收集回调中的响应式依赖。在需要精确控制触发条件的场景下,watch 更加合适。 ### 自定义 Hook:逻辑复用的利器 Composition API 最强大的能力之一是自定义 Hook,也称为组合函数(Composables)。通过将业务逻辑封装为独立的函数,可以在多个组件中复用。 下面是一个分页查询 Hook 的实现: ```javascript // usePagination.js import { ref, watch } from 'vue' export function usePagination(fetchFn, defaultPageSize = 10) { const list = ref([]) const loading = ref(false) const currentPage = ref(1) const pageSize = ref(defaultPageSize) const total = ref(0) async function fetchData(params = {}) { loading.value = true try { const res = await fetchFn({ page: currentPage.value, size: pageSize.value, ...params }) list.value = res.data total.value = res.total } catch (error) { console.error('请求失败:', error) } finally { loading.value = false } } function reset() { currentPage.value = 1 fetchData() } // 页码变化时自动请求 watch(currentPage, () => fetchData()) watch(pageSize, () => { currentPage.value = 1 fetchData() }) return { list, loading, currentPage, pageSize, total, fetchData, reset } } ``` 在组件中使用这个 Hook 非常简洁: ```javascript import { usePagination } from '@/composables/usePagination' import { getUserList } from '@/api/user' const { list: users, loading, currentPage, pageSize, total, reset } = usePagination(getUserList) ``` ### 依赖注入:跨层级组件通信 在深层嵌套的组件树中,Props 逐层传递非常繁琐。provide 和 inject 提供了一种优雅的解决方案。 ```javascript // 父组件提供用户信息 import { provide, readonly } from 'vue' const currentUser = ref(null) provide('currentUser', readonly(currentUser)) // 任意子组件注入使用 import { inject } from 'vue' const user = inject('currentUser') ``` 使用 readonly 包裹提供的值可以防止子组件意外修改父组件状态,这是一种良好的实践。如果子组件需要修改,应该通过 provide 传递修改方法。 ### 生命周期钩子 Composition API 中的生命周期钩子以 on 前缀命名,使用方式与 Options API 类似但更加灵活。 ```javascript import { onMounted, onUnmounted, onBeforeUnmount } from 'vue' onMounted(() => { fetchUsers() window.addEventListener('resize', handleResize) }) onBeforeUnmount(() => { window.removeEventListener('resize', handleResize) }) ``` ### 实战建议 第一,不要为了使用 Composition API 而过度拆分代码。如果一个组件逻辑简单,Options API 仍然是合理的选择。第二,自定义 Hook 应该保持单一职责,一个 Hook 只处理一个关注点。第三,善用 TypeScript 为 Hook 添加类型标注,提升开发体验和代码质量。 Composition API 并非完全取代 Options API,而是提供了一种更强大的代码组织方式。理解其设计理念,根据实际场景灵活选择,才能充分发挥 Vue 3 的能力。

1

0

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