Composables are Vue’s answer to “where does this logic live?” Done well, they make features portable across components without a single mixin.
A reusable async resource
export function useResource<T>(loader: () => Promise<T>) {
const data = ref<T | null>(null)
const error = ref<unknown>(null)
const loading = ref(false)
async function execute() {
loading.value = true
try {
data.value = await loader()
} catch (e) {
error.value = e
} finally {
loading.value = false
}
}
return { data, error, loading, execute }
}
<h2 id="keep-them-pure">Keep them pure</h2>
<p>:::info
A composable should own its own reactive state. Avoid reaching into global singletons unless it is genuinely shared (then make it a <code>useState</code>).
:::</p>
<h2 id="patterns-worth-knowing">Patterns worth knowing</h2>
<ul>
<li><strong>State factories</strong> for independent widget instances</li>
<li><strong>Async resources</strong> for any data fetch</li>
<li><strong>Lifecycle-aware</strong> logic that cleans up after itself</li>
</ul>
<blockquote>
<p>A good composable is a verb, not a noun: <code>use*</code>, not <code>widgetState</code>.</p>
</blockquote>
Comments
Comments are disabled for now. We're preparing a first-class experience powered by Giscus, Disqus or GitHub Discussions.