Vue·Intermediate
Vue 3 Composition API: Designing Maintainable Components
10 Aug 2026 · 8 min read · Intermediate
- #Vue
- #CompositionAPI
- #Architecture
Share
The Composition API is easy to start and easy to tangle. Maintainability comes from naming, extraction, and boundaries—not from using ref everywhere.
Prefer <script setup>
Vue
<script setup lang="ts">
import { computed, ref } from 'vue';
const props = defineProps<{ query: string }>();
const emit = defineEmits<{ select: [id: string] }>();
const open = ref(false);
const normalized = computed(() => props.query.trim().toLowerCase());
</script>Typed props and emits keep component contracts readable for teammates.
Extract composables by capability
Name composables after behavior, not framework mechanics:
useProjectFiltersuseInfiniteScrolluseClipboard
Avoid useStuff dumping grounds.
Typescript
import { computed, ref, type Ref } from 'vue';
export function useSearchFilter<T>(
items: Ref<T[]>,
predicate: (item: T, query: string) => boolean,
) {
const query = ref('');
const filtered = computed(() =>
items.value.filter((item) => predicate(item, query.value)),
);
return { query, filtered };
}State ownership
- Local UI:
ref/reactivein the component or composable - Cross-route client state: Pinia
- Server state: fetch layer + cache policy (do not shove HTTP into every component)
Template discipline
Composition API does not excuse 400-line SFCs. Split when you have:
- Multiple unrelated
watchblocks - Distinct visual regions with their own state
- Reused logic across pages
Conclusion
Treat composables as the Vue equivalent of well-named hooks: small, intentional, and easy to test without mounting the entire page.