Vue 3 组合式 API 的六个高级模式
Sarah Wong | 2026-08-26T23:00:35 | JavaScript, Frontend
深入探讨 Vue 3 Composition API 中 composables 提取、依赖注入、异步状态管理等六个高级用法。
# Vue 3 组合式 API 的六个高级模式 ## 模式一:可复用的 Composable ```typescript // composables/usePagination.ts import { ref, computed } from 'vue'; export function usePagination(fetchFn, pageSize = 10) { const currentPage = ref(1); const total = ref(0); const data = ref([]); const loading = ref(false); const totalPages = computed(() => Math.ceil(total.value / pageSize) ); async function loadPage(page) { loading.value = true; try { const res = await fetchFn(page, pageSize); data.value = res.items; total.value = res.total; currentPage.value = page; } finally { loading.value = false; } } return { currentPage, total, totalPages, data, loading, loadPage }; } ``` ## 模式二:Provide/Inject 依赖注入 ```typescript // 父组件提供主题 import { provide, ref } from 'vue'; const theme = ref('light'); provide('theme', { current: theme, toggle: () => { theme.value = theme.value === 'light' ? 'dark' : 'light'; } }); // 子组件注入 import { inject } from 'vue'; const { current, toggle } = inject('theme'); ``` ## 模式三:useAsyncState 异步状态 ```typescript export function useAsyncState(asyncFn) { const data = ref(null); const error = ref(null); const loading = ref(true); asyncFn() .then((res) => { data.value = res; }) .catch((err) => { error.value = err; }) .finally(() => { loading.value = false; }); return { data, error, loading }; } ``` ## 模式四:watchEffect 自动追踪 ```typescript import { watchEffect } from 'vue'; watchEffect((onCleanup) => { const controller = new AbortController(); fetch('/api/search?q=' + query.value, { signal: controller.signal }).then(r => r.json()).then(d => { results.value = d; }); onCleanup(() => controller.abort()); }); ``` ## 模式五:VueUse 式的事件组合 ```typescript export function useEventListener(target, event, handler) { onMounted(() => target.addEventListener(event, handler)); onUnmounted(() => target.removeEventListener(event, handler)); } ``` ## 模式六:状态机模式 ```typescript export function useMachine(config) { const state = ref(config.initial); function send(event) { const transitions = config.states[state.value]; if (transitions && transitions[event]) { state.value = transitions[event]; } } return { state, send }; } // 使用 const { state, send } = useMachine({ initial: 'idle', states: { idle: { FETCH: 'loading' }, loading: { SUCCESS: 'success', ERROR: 'error' }, success: { FETCH: 'loading' }, error: { RETRY: 'loading' }, } }); ```