可组合函数:可复用的组合式函数
将响应式逻辑提取到以 use 开头的可组合函数中,在组件之间共享,并了解它们与混入的区别。
可组合函数:可复用的组合式函数 是 CoddyKit 上的免费 Frontend Academy 课时。 这是第 4 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Frontend Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Frontend Academy 课程共包含 4 节课。
什么是组合式函数?
组合式函数是使用组合式 API 钩子来封装和复用有状态逻辑的函数。它们相当于组合式 API 版本的混入,但没有命名空间冲突或隐藏依赖。
基本组合式函数
将响应式逻辑提取到一个以 use 开头的函数中。它可以像 setup() 一样使用 ref、computed、watch 和生命周期钩子。
// useCounter.ts
import { ref } from 'vue';
export function useCounter(initial = 0) {
const count = ref(initial);
const increment = () => count.value++;
const decrement = () => count.value--;
const reset = () => (count.value = initial);
return { count, increment, decrement, reset };
}
// Usage in any component:
const { count, increment } = useCounter(10);带生命周期钩子的组合式函数
组合式函数可以注册生命周期钩子。钩子会相对于调用该组合式函数的组件触发。
// useOnlineStatus.ts
import { ref, onMounted, onUnmounted } from 'vue';
export function useOnlineStatus() {
const isOnline = ref(navigator.onLine);
const update = () => (isOnline.value = navigator.onLine);
onMounted(() => {
window.addEventListener('online', update);
window.addEventListener('offline', update);
});
onUnmounted(() => {
window.removeEventListener('online', update);
window.removeEventListener('offline', update);
});
return { isOnline };
}带异步操作的组合式函数(useFetch)
组合式函数非常适合异步数据获取——可以封装加载、错误和数据这一常见模式。
// useFetch.ts
export function useFetch<T>(url: MaybeRef<string>) {
const data = ref<T | null>(null);
const loading = ref(true);
const error = ref<string | null>(null);
watchEffect(async (onCleanup) => {
const controller = new AbortController();
onCleanup(() => controller.abort());
loading.value = true;
error.value = null;
try {
const res = await fetch(unref(url), { signal: controller.signal });
data.value = await res.json();
} catch (e: any) {
if (e.name !== 'AbortError') error.value = e.message;
} finally { loading.value = false; }
});
return { data, loading, error };
}接受 ref 作为参数
组合式函数可以使用 MaybeRef<T>(= T | Ref<T>)和 unref() 作为参数,从而接受普通值或 ref。
import type { MaybeRef } from 'vue';
import { unref } from 'vue';
function useDouble(num: MaybeRef<number>) {
return computed(() => unref(num) * 2);
}组合式函数与混入
混入会在没有明确来源的情况下向组件注入属性。组合式函数则明确清晰——您可以从其返回值准确看出它提供了什么。可以同时使用多个组合式函数,而不会产生命名冲突。
在组件之间共享状态
如果组合式函数在自身内部调用 ref(),每个调用它的组件都会获得自己的状态。要在组件之间共享状态,请在模块作用域中调用 ref()(位于组合式函数外部)。
// Shared state (module-level):
const sharedCount = ref(0);
export function useSharedCounter() {
// All callers share the same sharedCount
return { count: sharedCount, increment: () => sharedCount.value++ };
}组合式函数库
VueUse(vueuse.org)提供 200 多个可直接使用的组合式函数:useLocalStorage、useFetch、useDark、useIntersectionObserver 等。编写新代码前,请先查看 VueUse。
测试组合式函数
可以在小型测试组件中调用组合式函数来测试它们,也可以使用 @vue/test-utils 的 mountedApp 模式。Vitest 与 Vue 的响应式系统集成良好。
组合式函数命名约定
始终使用 use 作为前缀(useAuth、useFetch、useMediaQuery)。让每个组合式函数专注于单一职责。避免编写包含过多无关功能的组合式函数。
组合式函数的组织方式
创建一个 composables/ 文件夹。每个组合式函数使用一个文件。索引文件重新导出所有组合式函数。这与 React 项目中组织自定义钩子的方式相似。
快速检查
组合式函数相比 Vue 混入的主要优势是什么?
总结:Vue 组合式函数
组合式函数是以 use 为前缀、调用组合式 API 钩子的函数。除非使用模块级 ref,否则每个调用者都会获得独立的状态。使用 MaybeRef + unref 接受 ref 或普通值。在组合式函数内部注册生命周期钩子。编写自己的组合式函数前先查看 VueUse。明确的返回值可以避免混入式的命名空间污染。
常见问题解答
「可组合函数:可复用的组合式函数」课时是免费的吗?
是的 — 「可组合函数:可复用的组合式函数」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Frontend Academy 课程的其余内容,请升级到 CoddyKit PRO。 Frontend Academy 课程共包含 4 节课。
「可组合函数:可复用的组合式函数」这节课中我会学到什么?
将响应式逻辑提取到以 use 开头的可组合函数中,在组件之间共享,并了解它们与混入的区别。 你通过在浏览器中直接运行的动手代码来练习 Frontend Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 Frontend Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 Frontend Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 4 节课,共 4 节。
「可组合函数:可复用的组合式函数」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 Frontend Academy 课中编写并运行代码吗?
能。每节 Frontend Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。