Vue 3 Composition API: Flexible and Reusable Component Logic

Composition API vs Options API

Vue 2 Options API organizes by concern: data, methods, computed, watch (scattered across object sections). Vue 3 Composition API: group related logic in composables (functions). Options API example: data() { count: 0 }, methods: { increment() { this.count++ } }, computed: { doubled() { return this.count * 2 } }. Composition API equivalent: const count = ref(0), const increment = () => { count.value++ }, const doubled = computed(() => count.value * 2). Benefit: related state + methods grouped together. Complex components (50K+ lines) become unreadable with Options API (data/methods/computed scattered). Composition API scales: extract similar logic into composables, reuse across components without mixins (which cause namespace collision).

Reactivity System: Proxy-Based Tracking

Vue 2 uses Object.defineProperty (ES5, every property needs getter/setter). Vue 3 uses Proxy (ES6, intercepts all property access). Proxy tracks which properties accessed in render function: only those properties trigger re-render when changed. Example: reactive({ name: 'John', age: 30 }), render accesses name but not age, changing age does NOT re-render. getter/setter tracking: ref/computed create getters (dep tracking). Array changes: Proxy intercepts push/splice/sort, no need for Vue.set(). Change detection 10x faster than Vue 2. Reactivity scope: ref(value) returns { value: boxed value }, computed(getter) returns read-only ref, reactive({ ... }) returns Proxy object (no .value needed for top-level properties in template).

Lifecycle Hooks and Composition Timing

Options API: beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, beforeUnmount, unmounted. Composition API: use hooks (onBeforeMount, onMounted, onBeforeUpdate, onUpdated, onBeforeUnmount, onUnmounted) called inside setup. Timing matters: ref/computed created once in setup, reactive effects run on each render. Example: onMounted mounts canvas, onBeforeUnmount cleanup event listeners (prevent memory leak). Composables pattern: extract logic into reusable function (useMouse, useFetch, useIntersectionObserver). useEffect-like: watchEffect(callback) runs whenever dependencies change (auto-tracked). Alternatively, watch(source, callback, options) for explicit dependency list or lazy evaluation.

Script Setup Syntax and TypeScript Integration

<script setup> (Vue 3.3+): compiler transforms top-level code into setup function. Variables/functions automatically exposed to template (no return needed). Props: defineProps({ title: String, count: Number }). Emits: defineEmits(['increment', 'decrement']). Attributes: useAttrs() for inherited attributes (class, style). Slots: useSlots() for dynamic slots. Example: <script setup> const props = defineProps({ msg: String }), template uses props.msg directly. TypeScript: import type { PropType } from 'vue', defineProps({ message: String as PropType<string>, count: { type: Number as PropType<number>, required: true } }). Generic props: <script setup lang="ts" generic="T"> defineProps<{ item: T }>() (Vue 3.7+).

Tree-Shaking and Bundle Optimization

Composition API benefits: functions export individually, tree-shaking removes unused composables. Options API (Vue 2): monolithic components, dead code elimination harder. Vue 3 core (33KB gzipped) vs Vue 2 (34KB) similar, but with Composition API unused features drop from bundle. Plugins auto-install features only when used: @vueuse/core composables (~100KB total), but importing only useMouse/useFetch adds <5KB to bundle. TypeScript support: full type inference in templates (Vue 3.3+), template type-checking catches errors before runtime. Production: ref/reactive/computed create minimal runtime overhead (Proxy interception <1% CPU).

State Management and Context API

Composition API enables prop drilling avoidance via provide/inject. provide('theme', ref('dark')), inject('theme') in nested components. Pinia store (Vue 3 replacement for Vuex): defineStore('counter', { state: () => ({ count: 0 }), getters: { doubled: (state) => state.count * 2 }, actions: { increment() { this.count++ } } }). useStore() in components accesses state (reactive), getters (computed), actions. DevTools: Vue DevTools extension shows component tree, reactive state, events, performance timeline (component render time microseconds). Performance optimization: markRaw(object) prevents reactivity wrapping (immutable objects), shallowRef/shallowReactive for deep nesting performance.