Vue3 Vue Composition Api

Posted on  by admin

In this tutorial, we’ll explore how to use the Vue 3 Composition API and its latest code reusability capabilities. Code sharing and reusability are one of the cornerstones of software development. Since the earliest days of programming, the problem of code repetition has made programmers invent strategies for keeping their code DRY, reusable and portable.

As time has passed, these strategies have been constantly polished and improved, and new ones are constantly developed. This applies equally to Vue as to other programming languages and frameworks. As the Vue framework has evolved, it it has continued to offer much better reusability approaches. Let’s consider what makes a piece of code reusable.

Vue Composition API examples

For me, there are three main principles of reusability:. Code abstraction. A piece of code is abstract when it can suit multiple different use cases (like classes in many programming languages). Code portability. A piece of code is portable when it can be used not only in different places in one project but also in different projects.

Code decoupling (or loose coupling).

A piece of code is decoupled from another one when changing one doesn’t require changing the other. They’re as independent of each other as possible. Of course, complete decoupling is impossible — which is why the more accurate term used by developers is “loosely coupled”. The Composition API is a new strategy for building and structuring Vue 3 components.

It incorporates all of the three principles described above and allows for creating abstract, portable, and loosely coupled components that can be reused and shared between different projects. The motivation for the Composition API to be added to Vue 3 is clear and simple: producing more compact and defragmented code.

Let’s explore this a bit more. When I found Vue for the first time, I was hooked by its Options (object-based) API.

It seemed to me way more clear and elegant in contrast to the Angular and React equivalents. Everything has its own place and I can just put it in there. When I have some data, I put it in a data option; when I have some functions, I put them in a methods option, and so on:.

All this seems quite ordered, clean, and easy to read and understand. It turns out, however, that this is valid only while an app is relatively small and simple. As the app and its components grow more and more, the code fragmentation and disorder increase.

When the Options API is used in large projects, the code base soon starts to become like a fragmented hard disk.

What Is Composition API and Why It Was Created

Different parts of the code in a component, which logically belong together, are spread in different places.

Creating and Using Vue Composables

This makes the code hard to read, understand and maintain. This is where the Composition API comes into play.

It offers a way to structure the code in order, where all logical parts are grouped together as a unit. To some extent, you can imagine the Composition API as a disk defragmentation tool. It helps you to keep the code compact and clean. Here’s a simplified visual example:. As you can see, a component’s code built with Options API could be quite fragmented, while a component’s code built with the Composition API is grouped by features and looks much easier to read and maintain.

Here’s a summary of the main advantages the Composition API offers:. Better code composition. Logically related blocks are kept together. Better overall performance compared to Vue 2. The code is logically better ordered, which makes it much more meaningful and easy to read and understand.

Browse other questions tagged vue.jsvuejs3vue-composition-api or ask your own question.

Easy to extract and import functionality. TypeScript support, which improves IDE integrations and code assistance, and code debugging. (This is not a feature of the Composition API, but it’s worth mentioning it as a feature of Vue 3.).

Despite its power and flexibility the Composition API is quite simple. To use it in a component, we need to add a setup() function, which in fact is just another option added to the Options API: .

Use Vue 3 Composition API in current Vue 2 project

Inside the setup() function, we can create reactive variables, and functions to manipulate them.

Then we can return those variables and/or functions, which we want to be available in the rest of the component. To make reactive variables, you’ll need to use the Reactivity API functions (ref(), reactive(), computed(), and so on).

What Are Vue Composables?

To learn more about their usage, you can explore this comprehensive tutorial about the Vue 3 Reacivity system.

  • The setup() function accepts two arguments: props and context.
  • Props are reactive and will be updated when new props are passed in:.
  • If you want to destructure your props, you can do this by using toRefs() inside the setup() function.

If you use ES6 destructuring instead, it will remove props reactivity:.

Context is a normal JavaScript object (not reactive) that exposes other useful values like attrs, slots, emit. These are equivalents to $attrs, $slots, and $emit from the Options API. The setup() function is executed before the component instance creation.

So you won’t have access to the following component options: data, computed, methods, and template refs. In the setup() function, you can access a component’s lifecycle hook by using the on prefix. For example, mounted will become onMounted. The lifecycle functions accept a callback that will be executed when the hook is called by the component:.

Note: you don’t need to call the beforeCreate and created hooks explicitly, because the setup() function does a similar job by itself. In a setup() function, this isn’t a reference to the current active instance, because setup() is called before other component options are resolved. Let’s make a quick comparison between the Options and Composition APIs.

First, here’s a simple to-do app component, built with the Options API, with abilities to add and remove tasks:. I’ve omitted the CSS code here for brevity and because it’s not relevant.

Source Code

You can see the full code in the Vue 2 Options API example. As you can see, this is quite a simple example. We have three data variables and two methods. Let’s see how to rewrite them with the Composition API in mind:.

As you can see in this Vue 3 Composition API example, the functionality is the same but all data variables and methods are moved inside a setup() function.

To recreate the three data reactive variables, we use the ref() function.

Then, we recreate the addNewTodo() and removeTodo() functions. Note that all uses of this are removed and instead variable names are used directly followed by the value property.

So instead of this.newItemText we write newItemText.value, and so on. Finally, we return the variables and functions so they can be used in the component’s template.

Note that, when we use them in the template, we don’t need to use the value property, because all returned values are automatically shallow unwrapped. So we don’t need to change anything in the template.

We make the name and tasks read-only to prevent them from any changes outside of the component. In this case, the tasks property can be changed only by addNewTodo() and removeTodo().

Just because some new technology is created doesn’t mean you need it or must use it. Before deciding whether to use a new technology, you should think about whether you really need it. Although the Composition API offers some great benefits, using it in small and simple projects can lead to unnecessary complexity. The principle is the same as with Vuex usage: it can be too complicated for small projects. For example, if your components are mostly single-feature — that is, they do only one thing — you don’t need to add unnecessary cognitive load by using the Composition API.

But if you notice that your components are getting complex and multi-featured — they handle more than one single task and/or their functionality is needed in many places in you app — then you should consider using the Composition API.

Motivation to Add the Vue Composition API to the Framework

In medium to large projects with lots of complex, multi-featured components, the Composition API will help you produce highly reusable and maintainable code without unnecessary hacks or workarounds. So you can take the following rules as a general advice:.


The Options API is best for building small, simple, single-feature components whose functionality requires low reusability. The Composition API is best for building larger and more complex, multi-featured components whose functionality requires higher reusability.

The secret weapon of the Composition API is the ability to create highly reusable modules called composables.

They allow us to extract reactive state and functionality and reuse it in other components. Composables are the equivalent of mixins in the Options API. They can be considered also as an equivalent to React hooks. Before composables, there were three ways to reuse and share code between components: utility functions, mixins, and renderless components.

But composables beat them all. Utility functions are useful but limited, because they can’t handle Vue-specific features like reactive state.

Here’s an example:. Here, we have an increment(count) utility function that increments the count variable by one.

But we can’t define reactive state here. We need to add a reactive count variable inside the consuming component, like this:.

Renderless components (which are components that doesn’t render any HTML templates, but only state and functionality) are a bit better than utility functions, because they can handle Vue-specific features, but their flexibility is also limited. Here’s an example:. It’s a bit better here, because we can define reactive state and export it with the help of scoped slots. When we implement the component, we use the defined count variable and increment() method to build a custom template:.


Mixins are the official way of code sharing between components built with the Options API. A mixin is just an exported options object:. We can import the mixin’s options object and use it as if its members belongs to the consuming component’s options object:. If a component has already defined some options (data, methods, computed, and so on), they’re merged with those from the imported mixin(s).

As we’ll see shortly, this behavior has some serious disadvantages.

Mixins have some serious drawbacks compared with composables:. Data source is obscured. When a component’s data comes from multiple mixins, we can’t say for sure which properties came from which mixin.

The same is true when globally registered mixins are used. Restricted reusability. Mixins don’t accept parameters, so we can’t add additional logic. Name conflicts. If two or more mixins have properties with the same name, the property from the last mixin will be used, which might not be what we want. No data safeguarding.

Further Reading

We can’t be sure that a mixin’s property won’t be changed by the consuming component. As a conclusion to this section, let’s summarize the main benefits of Vue 3 composables:.

Data source is transparent. To use composables, we need to import them and use destructuring to extract the desired data. So we can see clearly the source of every property/method.

Up Next

No name conflicts. We can use properties with same names coming from multiple composables just by renaming them. Data is safeguarded.

  1. We can make the returned properties read-only, thus restricting mutation coming from other components.
  2. The principle is the same as with mutations in Vuex. Usually every composable used in a component creates a new local state.
  3. But we can also define global state, so that when composables are used in different components, they’ll share the same state. In this section, we’ll learn how to create and use custom Vue 3 composables.

Using the Composition API with Vue 2

Note: for this project, you’ll need Node and Vue CLI installed on your machine. Let’s create a new Vue 3 project by using the Vue CLI:.

When you’re asked to pick a preset, make sure you’ve chosen the default Vue 3 option. You can find all project files in the Vue Composition API examples repo. In the following example, we’ll create a custom data-fetching composable that can be used in a variety of scanarios.

First, create a src/composables folder and add an useFetch.js file to it.

Here’s the code for that file:. Technically, a composable is just a function we export (useFetch() in our case).


In that function, we create data and state variables. Then we create a fetchData() function, in which we use the Fetch API to get data from a particular source and assign the result to the data property. After the fetchData() function, we immediately call it in order to assign the variables with the fetched data.

Lastly, we return all variables.

We use toRefs() here to properly extract error and loading variables, keeping them reactive. Now, let’s see how we can use our composable in a component.

Vue setup() function

In the src/components folder, add a UserList.vue file with the following content:. Here, we import the useFetch() composable and then extract its variables inside the setup() function.

What Makes the Composition API Better than the Options API?

After we’ve returned the variables, we can use them in the template to create a list of users. In the template, we use the v-if directive to check the truthiness of error and loading, and if one of them is true, the appropriate message is shown.

Then, we use the v-for directive and data property to create the actual list of users.

The last thing we need to do is add the component in the App.vue file.

Composition API Basics

this.$refs with new Composition API

Open the App.vue file and replace its content with the following:. This is the base for creating and using composables. But let’s go further and make the user list component a bit more flexible and reusable. Rename UserList.vue to UniversalList.vue and replace its content with the following:.