跳到主要内容

认识组合函数

在 Vue 3 的组合式 API(Composition API)生态中,组合函数(Composable Functions,常简称为 Composables)是一种封装和复用逻辑的函数,它利用 refreactivecomputedwatchprovide/inject 等响应式 API,将相关逻辑组织在一起,并可被多个组件共享。

核心思想:把“逻辑”从组件中抽离出来,实现关注点分离逻辑复用,类似 React 中的自定义 Hooks。


🌰 一个简单例子:useMouse

// composables/useMouse.js
import { ref, onMounted, onUnmounted } from 'vue'

export function useMouse() {
const x = ref(0)
const y = ref(0)

const update = (e) => {
x.value = e.pageX
y.value = e.pageY
}

onMounted(() => {
window.addEventListener('mousemove', update)
})

onUnmounted(() => {
window.removeEventListener('mousemove', update)
})

return { x, y }
}

在组件中使用:

<!-- MouseTracker.vue -->
<script setup>
import { useMouse } from '@/composables/useMouse'

const { x, y } = useMouse()
</script>

<template>
<div>鼠标位置:{{ x }}, {{ y }}</div>
</template>

✅ 这个 useMouse 就是一个典型的组合函数


🧩 为什么需要组合函数?

在 Options API(选项式 API)中,逻辑复用靠 mixins,但 mixins 存在:

  • 命名冲突
  • 来源不清晰(“魔法属性”)
  • 难以类型推导(尤其在 TS 中)

而 Composables:

  • 显式导入/导出,来源清晰
  • 无命名冲突(通过解构重命名)
  • 天然支持 TypeScript
  • 更贴近函数式编程思想

🛠 常见应用场景

场景组合函数示例
数据请求useFetch(url)
本地存储useLocalStorage(key, defaultValue)
表单验证useValidation(rules)
计时器useInterval(fn, delay)
路由守卫逻辑useAuthRedirect()
主题切换useTheme()

📦 示例:useLocalStorage

// composables/useLocalStorage.js
import { ref, watch } from 'vue'

export function useLocalStorage(key, defaultValue) {
const stored = localStorage.getItem(key)
const value = ref(stored ? JSON.parse(stored) : defaultValue)

watch(value, (newValue) => {
localStorage.setItem(key, JSON.stringify(newValue))
}, { deep: true })

return value
}

使用:

const count = useLocalStorage('count', 0)
// 修改 count.value 会自动同步到 localStorage

⚠️ 注意事项

  1. 只能在 setup()<script setup> 中调用
    因为它们依赖 Vue 的响应式上下文(如 currentInstance)。

  2. 不要在条件语句或循环中调用(类似 React Hooks 规则)
    虽然 Vue 没有严格限制,但为了可预测性,建议始终在顶层调用。

  3. 命名规范:以 useXxx 开头,便于识别。

  4. 文件组织:通常放在 src/composables/ 目录下。