JavaScript

Vue.js 3 Composition API: A Complete Guide for 2024

· 12 min read
Vue.js 3 Composition API: A Complete Guide for 2024

[TOC]

Vue.js 3 Composition API: A Complete Guide for 2024

The Vue.js 3 Composition API represents a paradigm shift in how we write Vue applications. This comprehensive guide will help you master this powerful feature and understand when and how to use it effectively.

Understanding the Composition API

The Composition API provides a new way to organize component logic in Vue.js applications. Instead of spreading related code across different options, you can group it together based on functionality.

Why Use the Composition API?

  1. Better TypeScript Support
  2. More Flexible Code Organization
  3. Better Code Reuse
  4. Improved Runtime Performance

Getting Started

Basic Setup

import { ref, onMounted } from 'vue'

export default {
  setup() {
    // Reactive state
    const count = ref(0)

    // Methods
    const increment = () => {
      count.value++
    }

    // Lifecycle hooks
    onMounted(() => {
      console.log('Component mounted')
    })

    // Expose to template
    return {
      count,
      increment
    }
  }
}

Reactive State Management

import { ref, reactive } from 'vue'

export default {
  setup() {
    // Using ref for primitive values
    const name = ref('John')

    // Using reactive for objects
    const user = reactive({
      firstName: 'John',
      lastName: 'Doe',
      age: 30
    })

    return {
      name,
      user
    }
  }
}

Creating Composables

Composables are the Composition API's way of reusing stateful logic:

// useCounter.js
import { ref } from 'vue'

export function useCounter(initialValue = 0) {
  const count = ref(initialValue)

  const increment = () => {
    count.value++
  }

  const decrement = () => {
    count.value--
  }

  return {
    count,
    increment,
    decrement
  }
}

Using Composables

import { useCounter } from './composables/useCounter'

export default {
  setup() {
    const { count, increment, decrement } = useCounter(10)

    return {
      count,
      increment,
      decrement
    }
  }
}

Advanced Patterns

Computed Properties

import { ref, computed } from 'vue'

export default {
  setup() {
    const firstName = ref('John')
    const lastName = ref('Doe')

    const fullName = computed(() => {
      return `${firstName.value} ${lastName.value}`
    })

    return {
      firstName,
      lastName,
      fullName
    }
  }
}

Watchers

import { ref, watch } from 'vue'

export default {
  setup() {
    const searchQuery = ref('')

    watch(searchQuery, async (newValue, oldValue) => {
      if (newValue.length >= 3) {
        await performSearch(newValue)
      }
    })

    return {
      searchQuery
    }
  }
}

Best Practices

1. Keep Composables Focused

Create small, focused composables that handle one specific concern:

// Good
function useUserAuthentication() { ... }
function useNotifications() { ... }

// Avoid
function useUserAuthenticationAndNotifications() { ... }

2. Consistent Naming Conventions

  • Prefix composables with 'use'
  • Use clear, descriptive names
  • Keep naming consistent across your application

3. Type Safety

interface User {
  id: number
  name: string
  email: string
}

function useUser() {
  const user = ref<User | null>(null)

  const fetchUser = async (id: number): Promise<void> => {
    user.value = await api.getUser(id)
  }

  return {
    user,
    fetchUser
  }
}

Common Pitfalls to Avoid

  1. Forgetting .value with refs
  2. Destructuring reactive objects
  3. Not properly typing composables
  4. Overusing global state
  5. Creating too large composables

Performance Optimization

1. Lazy Loading Components

const MyLargeComponent = defineAsyncComponent(() =>
  import('./components/MyLargeComponent.vue')
)

2. Memo-ization

import { computed } from 'vue'

const memoizedValue = computed(() => {
  return expensiveOperation(dependencyValue.value)
})

Testing Composition API Code

import { mount } from '@vue/test-utils'
import { useCounter } from './useCounter'

test('useCounter', () => {
  const wrapper = mount({
    template: '<div>{{ count }}</div>',
    setup() {
      return {
        ...useCounter()
      }
    }
  })

  expect(wrapper.text()).toBe('0')
})

Migration Strategies

When moving from Options API to Composition API:

  1. Start with new features
  2. Gradually refactor existing components
  3. Create composables for shared logic
  4. Update tests as you go
  5. Document patterns and decisions

Conclusion

The Vue.js 3 Composition API offers a more flexible and powerful way to organize component logic. By following these patterns and best practices, you can create more maintainable and scalable Vue applications.

Key takeaways:

  • Use composables for code reuse
  • Maintain type safety
  • Follow consistent patterns
  • Test thoroughly
  • Optimize performance
  • Document your code

Happy coding! 🚀

Share this article