我最近与 Vue Storefront 团队进行了一次很好的讨论,关于编写组合式API的模式。在我们的系统中,组合式API负责存储主要的业务逻辑(如计算、操作、流程),因此它们是应用程序的重要组成部分。。
我很高兴现在来重构组合式API的方法,使它们易于维护、易于测试,并且真正有用。
在本文中,我将总结我们创建的思路,并将它们与我在几篇文章中读到的良好实践和设计模式结合起来。
因此,本文将分为三个部分:
- 通用设计模式
- 我的建议
- 进一步阅读
通用设计模式
在我看来,学习构建组合式API的最佳资料是 Vue.js 文档,你可以在这里查看。
基本组合式函数
Vue 文档展示了以下 useMouse 的示例:
// mouse.js
import { ref, onMounted, onUnmounted } from 'vue'
// 按惯例,组合式函数名称以 "use" 开头
export function useMouse() {
// 由组合式函数封装和管理的状态
const x = ref(0)
const y = ref(0)
// 组合式函数 可以随着时间的推移更新其管理的状态
function update(event) {
x.value = event.pageX
y.value = event.pageY
}
// 组合式函数还可以挂钩到其所有者组件的生命周期,以设置和清理副作用
onMounted(() => window.addEventListener('mousemove', update))
onUnmounted(() => window.removeEventListener('mousemove', update))
// 将管理的状态作为返回值暴露
return { x, y }
}
在组件中如下使用:
Mouse position is at: {{ x }}, {{ y }}
异步组合式API
对于获取数据,Vue 推荐以下的结构:
import { ref, watchEffect, toValue } from 'vue'
export function useFetch(url) {
const data = ref(null)
const error = ref(null)
watchEffect(() => {
// 在获取之前重置状态..
data.value = null
error.value = null
// toValue() 解包潜在的 ref 或 getter
fetch(toValue(url))
.then((res) => res.json())
.then((json) => (data.value = json))
.catch((err) => (error.value = err))
})
return { data, error }
}
在组件中如下使用:
组合式API约定
根据上述示例,所有组合式API应遵循以下约定:
- 组合式函数文件名应以 use 开头,例如 useSomeAmazingFeature.ts
- 接收输入参数,可以是字符串等原始类型,也可以是 refs 和 getters,但需要使用 toValue 辅助函数
- 组合式API应返回一个 ref 值,可以在解构后访问,例如 const { x, y } = useMouse()
- 组合式API可以持有全局状态,可以在应用程序中访问和修改
- 组合式API 可以产生副作用,例如添加窗口事件监听器,但应在组件卸载时清理
- 组合式API 应仅在