Modified10 months ago. Trying to switch my code to the new composition API that comes with Vue 3 but I cant get it to work.
33 gold badges3232 silver badges6363 bronze badges. 6363 bronze badges. skip "computed" all togetheryou need to use "ref" or "reactive".
- these are modules:. if you want to use classes you import them like in this example of my own:.
- Now "api" can be used inside setup() or wherever.
Modified5 months ago. Im playing along with the new Vue plugin for using composition API and TypeScript and there is something I'm not quite understanding.
How am I supposed to type computed properties? In this simple example I'm declaring two refs and a computed property to join both.
VSC is telling me that computed properties are returning ReadOnly type.. But I can't make it work.
5454 bronze badges. 47911 gold badge88 silver badges1313 bronze badges. 88 silver badges1313 bronze badges. There are two different types for that. If your computed prop is readonly:.
if it has a setter method:. 66 gold badges7272 silver badges106106 bronze badges. 106106 bronze badges.
88 gold badges3636 silver badges8080 bronze badges1. 8080 bronze badges.
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. 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.
Creating and Using Vue Composables
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. Different parts of the code in a component, which logically belong together, are spread in different places.
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.
Composition API Basics
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: .
- 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).
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:.
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.
What is the Vue 3 composition API?
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.
Not the answer you're looking for? Browse other questions tagged vuejs3 or ask your own question.
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.
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.
What Are Vue Composables?
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.
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. 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. No name conflicts. We can use properties with same names coming from multiple composables just by renaming them.
The principle is the same as with mutations in Vuex. Usually every composable used in a component creates a new local state. 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. 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.
Here’s the code for that file:. Technically, a composable is just a function we export (useFetch() in our case).
Not the answer you're looking for? Browse other questions tagged typescriptvue.jsvue-composition-api or ask your own question.
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.
|Options API||Hook inside setup()|
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.
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.