How to use Composition API the right way
Tags: javascript, vue, compositionapi
Published: 2022-08-16 19:24:00

## Intro

In this article we are going to explore why we should use Composition API and how to do it properly. 

## Why not the old Options API way?

First of all, even though the Options API is not deprecated, reading through the docs you will see that it is discouraged and the new recommended way is Composition API and script setup.

From the docs:

> - Go with Options API if you are not using build tools, or plan to use Vue primarily in low-complexity scenarios, e.g. progressive enhancement.
>
> - Go with Composition API + Single-File Components if you plan to build full applications with Vue.


> If you intend to exclusively use Composition API (along with the options listed above), you can shave a few kbs off your production bundle via a compile-time flag that drops Options API related code from Vue


> Options API does allow you to "think less" when writing component code, which is why many users love it. However, in reducing the mental overhead, it also locks you into the prescribed code organization pattern with no escape hatch, which can make it difficult to refactor or improve code quality in larger scale projects. In this regard, Composition API provides better long term scalability.

So in short, using Composition API instead of Options API gives you performance benefits, provides better long term scalability and is the recommended way if you plan to build full applications.

## Why Composition API is indeed better?

Now that we understood that Composition API is better and is the recommended way to write components, let's try to understand why.

With Options API we could have a code like this:

```js
export default {
    data: () => ({
        count: 0,
        newUser: ''
        newTodo: ''
    }),

    computed: {
        filteredTodos(){ /*...*/ },
        filteredUsers(){ /*...*/ }
    },

    methods: {
        doubleCount(){ /*...*/ },
        addAndClearUser(){ /*...*/ },
        addAndClearTodo(){ /*...*/ }
    }
}
```

This component deals with 3 logical concerns: count, user, and todo. At a first glance we don't see an issue because the component is very small but if we add more to that component, we will see that the logical concerns are forced to be split under different options,  located in different parts of the file.

Now that we know the issue, let's see how we can solve it with the Composition API:

```js
import { ref, computed } from 'vue'

// Count
const count = ref(0)
function doubleCount(){ /*...*/ }

// User
const newUser = ref('')
const filteredUsers = computed(() => { /*...*/ })
function addAndClearUser(){ /*...*/ }

// Todo
const newTodo = ref('')
const filteredTodos = computed(() => { /*...*/ })
function addAndClearTodo(){ /*...*/ }
```

Notice how the code related to the same logical concern can now be grouped together: we no longer need to jump between different options blocks while working on a specific logical concern.

So now with Composition API we don't have to scroll up and down to find the code related to a specific logical concern.

What's even more exciting is that we can move a group of code into an external file with minimal effort, since we no longer need to shuffle the code around (like with Options API) in order to extract them. So if we were to do that our component would look like this:

```js
import { useCount, useUser, useTodo } from './composables'

const { count, doubleCount } = useCount()
const { newUser, filteredUsers, addAndClearUser } = useUser()
const { newTodo, filteredTodos, addAndClearTodo } = useTodo()
```

Amazing isn't it? 😎🆒

## How to structure logical concerns?

So while the key takeaway from Composition API is that we need to group code related to a specific logical concern together, I have experienced that the code can be hard to read and understand if there is no consistency.


So we need to **organize a logical concern in a consistent way**.
Personally, I organize the logical concerns as if I were to write it with Options API. So in the following order:

```js
<script setup>
// Props (defineProps)
// Emits (defineEmits)
// Reactive variables (inc composables)
// Computed
// Methods
// Watchers
// Lifecycle Hooks
// Expose (defineExpose)
</script>
```

*Let me know in the comments if you use a different way of organizing a logical concern.*

By using this consistent way of organizing logical concerns, the code is easier to read and understand.

Another pattern I have seen, is adding a comment before each logical concern to differentiate between them. Personally, I use this pattern and it has helped me reading the code easier so I highly recommend it.

*For example:*

```js
<script setup>
import { ref } from 'vue'

// Count 👈 this
const count = ref(0)
function doubleCount(){ /*...*/ }

// User 👈 this
const newUser = ref('')
function addAndClearUser(){ /*...*/ }
</script>
```

Lastly, I always prefer `function` declaration over `const` (arrow functions) for functions. That has resulted a good pattern and one reason is that you won't get `Uncaught ReferenceError: Cannot access '<variable>' before initialization` 😉.

## Conclusion

I hope this article helped you to understand why Composition API is a better way to write components and how to use it properly. In the beginning you might not immediately see the benefits, but as your application grows, you will thank yourself for using it.

Composition API has unlocked a lot of possibilities and it enables clean and efficient logic reuse. It's just a matter of time falling in love with it but you have to use it the right way and so far in my experience I have seen many devs using it the wrong way.

Thanks for reading this article and make sure to leave a like and share with your network if you liked it. 🎉

<a href="https://www.buymeacoffee.com/rolanddoda" target="_blank"><img src="https://cdn.buymeacoffee.com/buttons/default-orange.png" alt="Buy Me A Coffee" height="41" width="174"></a>