# Vue 3 Composition API: Complete Guide to Mastering Reactivity > Master Vue 3 Composition API with this practical guide. Learn ref, reactive, computed, watch, and composables to build performant Vue applications. - Published: 2026-01-07 - Updated: 2026-03-31 - Author: SharpSkill - Tags: vue 3, composition api, javascript, frontend, reactivity - Reading time: 12 min --- The Vue 3 Composition API represents a major evolution in how Vue components are structured. This approach organizes code by feature rather than by option, making it easier to reuse logic and maintain complex applications. > **Prerequisites** > > This guide assumes basic knowledge of Vue.js. Examples use the ` ``` For objects with multiple related properties, `reactive` offers a more natural syntax without needing `.value`. ```javascript // UserProfile.vue ``` The general rule: use `ref` for primitive values (string, number, boolean) and `reactive` for structured objects. ## Computed Properties with computed Computed properties derive values from reactive state. They are cached and only recalculate when their dependencies change, making them highly performant. ```javascript // ProductList.vue ``` Computed properties can also be writable with a getter and setter, useful for bidirectional transformations. ```javascript // FullName.vue ``` ## Watchers with watch and watchEffect Watchers execute side effects in response to data changes. Vue 3 offers two approaches: `watch` for precise control and `watchEffect` for automatic tracking. > **When to use watch vs watchEffect?** > > `watch` offers precise control over dependencies and provides both old and new values. `watchEffect` is simpler when all reactive dependencies used should trigger the effect. ```javascript // SearchComponent.vue ``` To observe nested objects or arrays, the `deep` option is necessary with `watch`. ```javascript // DeepWatch.vue ``` ## Creating Reusable Composables Composables are functions that encapsulate reusable reactive logic. This approach is one of the major strengths of the Composition API for sharing code between components. ```javascript // composables/useFetch.js import { ref, watchEffect, toValue } from 'vue' // Composable for HTTP requests // Automatically handles loading, errors, and refetching export function useFetch(url) { const data = ref(null) const error = ref(null) const isLoading = ref(false) // Reusable fetch function async function fetchData() { isLoading.value = true error.value = null try { // toValue() allows accepting a ref or a value const response = await fetch(toValue(url)) if (!response.ok) { throw new Error(`HTTP ${response.status}`) } data.value = await response.json() } catch (e) { error.value = e.message } finally { isLoading.value = false } } // watchEffect for automatic refetch if url is a ref watchEffect(() => { fetchData() }) // Expose state and methods return { data, error, isLoading, refetch: fetchData } } ``` This composable can then be used declaratively in any component. ```javascript // UserList.vue ``` Here is another example of a composable for managing form state with validation. ```javascript // composables/useForm.js import { reactive, computed } from 'vue' // Form management composable export function useForm(initialValues, validationRules) { // Form state const form = reactive({ values: { ...initialValues }, errors: {}, touched: {} }) // Validate a specific field const validateField = (field) => { const rules = validationRules[field] if (!rules) return true for (const rule of rules) { const result = rule(form.values[field]) if (result !== true) { form.errors[field] = result return false } } form.errors[field] = null return true } // Validate entire form const validate = () => { let isValid = true for (const field in validationRules) { if (!validateField(field)) { isValid = false } } return isValid } // computed: form is valid if no errors const isValid = computed(() => { return Object.values(form.errors).every(e => !e) }) // Mark a field as touched (to display errors) const touch = (field) => { form.touched[field] = true validateField(field) } // Reset the form const reset = () => { form.values = { ...initialValues } form.errors = {} form.touched = {} } return { form, isValid, validate, validateField, touch, reset } } ``` ## Lifecycle Hook Management The Composition API provides lifecycle hooks as functions to call within setup. These hooks execute code at specific moments in the component's lifecycle. > **Important Cleanup** > > Always clean up side effects (timers, event listeners, subscriptions) in `onUnmounted` to avoid memory leaks. ```javascript // LifecycleDemo.vue ``` ## Template Refs and DOM Access Template refs provide direct access to DOM elements or child component instances. This remains useful for cases where direct manipulation is necessary. ```javascript // InputFocus.vue ``` ## Parent-Child Communication with Props and Emits The Composition API modernizes props and events declaration with `defineProps` and `defineEmits`, offering better TypeScript integration. ```javascript // ChildComponent.vue ``` ```javascript // ParentComponent.vue ``` ## Provide and Inject for Dependency Injection To share data between distant components without prop drilling, Vue 3 offers `provide` and `inject`. ```javascript // App.vue (or an ancestor component) ``` ```javascript // DeepNestedComponent.vue (anywhere in the tree) ``` ## Conclusion The Vue 3 Composition API offers a powerful and flexible approach to organizing Vue application code. Key concepts to remember: - ✅ **ref** for primitive values, **reactive** for complex objects - ✅ **computed** for derived values with automatic caching - ✅ **watch** and **watchEffect** for reactive side effects - ✅ **Composables** to extract and reuse logic between components - ✅ **Functional lifecycle hooks** (`onMounted`, `onUnmounted`, etc.) - ✅ **provide/inject** for dependency injection without prop drilling This approach facilitates creating maintainable and testable applications while offering excellent TypeScript integration. The next step involves exploring advanced patterns like async composables and integration with Pinia for global state management. --- Source: SharpSkill (https://sharpskill.dev), tech interview preparation for your real stack. HTML version of this page: https://sharpskill.dev/en/blog/vue-nuxt/vue-3-composition-api-complete-guide