跳到主要内容

认识组合函数

组合函数(Composable)使用 Vue 响应式 API 封装可复用的有状态逻辑,通常命名为 useXxx,放在 src/composables/ 中。与 mixin 相比,显式导入和返回值更容易追踪来源、避免名称冲突。

示例:鼠标位置​

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

export function useMouse() {
const x = ref(0);
const y = ref(0);
const update = event => {
x.value = event.pageX;
y.value = event.pageY;
};

onMounted(() => window.addEventListener('mousemove', update));
onUnmounted(() => window.removeEventListener('mousemove', update));
return { x, y };
}
<script setup>
import { useMouse } from '@/composables/useMouse';
const { x, y } = useMouse();
</script>

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

每次调用会创建独立状态。需要跨组件共享时,可将状态移到外部,或使用依赖注入、状态管理方案。

示例:本地存储​

以下示例限浏览器端调用,并假设存储内容是合法 JSON。

import { ref, watch } from 'vue';

export function useLocalStorage(key, defaultValue) {
const stored = localStorage.getItem(key);
const value = ref(stored === null ? defaultValue : JSON.parse(stored));
watch(value, nextValue => {
localStorage.setItem(key, JSON.stringify(nextValue));
}, { deep: true });
return value;
}

使用:const count = useLocalStorage('count', 0)。实际项目需处理 JSON 解析、存储容量或访问失败;此示例不负责跨标签页同步。

使用约定​

  • 返回包含 ref 的普通对象,方便调用方解构并保留响应性。
  • 动态输入可接受 ref 或 getter,在副作用内部使用 toValue 读取。
  • 使用生命周期或依赖注入的函数,应在有效上下文中同步调用;仅依赖响应式 API 的函数也可在组件外配合 effectScope 使用。
  • Vue 不要求像 React Hooks 一样禁止条件或循环调用,但仍需保证资源注册与清理成对。
  • SSR 场景的 DOM 操作放在 onMounted(),全局事件、计时器等显式清理。

常见用途包括请求状态、表单验证、本地存储、主题与计时器。参考:组合式函数。