Here is a hello-world level of introduction to the new composition API released in Vue 3. For a more thorough explanation, you may want to refer to the official document from Vue here.
Vue’s composition API provides a way to write your Vue component in a functional programming flavor by organizing variables and methods by purpose, rather than by their types in the traditional way (or called the Options API). Let’s put the difference of code organization in pseudo-code:. - variable 1 for activity 1.
- variable 2 for activity 2. - function1 for activity 1. - function2 for activity 2. - variable 1 for activity 1. - function1 for activity 1.
Replacing lifecycle hooks
- variable 2 for activity 2. - function2 for activity 2. Such organization can be helpful when your Vue component grows larger and start to include multiple activities.
- Adding or modifying on activity would not require editing multiple parts of the code if it is designed in composition API.
- Let’s say, we are creating a Vue app of two counters. You might imagine that we would need to create two variables and two functions to handle different activities.
- Below is the same code presented in Options API and Composition API respectively. Objects are ordered by their types. Variables are stored in data option. Functions are stored in methods option. With composition API, objects inside the scripts part can be rearranged to a functional programming flavored design.
Variables and methods are now grouped together by their purposes. In the very simple composition API example above, two new keywords are introduced:. Serves as a single entry point to the composition API. All objects defined in scripts need to be returned here and it is executed before the component is created.
This is a wrapper for variables to allow them be accessed else where in the scripts part. A quick reasoning of creating a ref function in Vue 3 is provided in the official document here.
One thing to be noted is that the value of the variable wrapped need to be accessed by its .value property. Here is only a very simple example to the newly introduced composition API in Vue 3. Apart from data and methods, there are relevant mapping of computed, props/emit and etc. from the Options API to Composition API. You might want to migrate you current Vue code into the new style if you find it cleaner to organize your code in a functional programming design.
In this Vue tutorial we learn a different way to write component logic with the Composition API. We cover how to move to the new setup option and how to replace options from the Options API with their new function counterparts.
Replacing the data option with ref(). Replacing the watch option with watch(). If you want to follow along with the examples, you will need to create an app generated by the Vue CLI. As mentioned in the Vue API lesson, the Composition API combines all of a component’s data and functionality into a single section.
Instead of separating our code into different options likedata,methods,computedetc. we now use only thesetupoption. The Composition API’s only focus is changing how the data, methods, watchers and computed options of a component can be written differently.
Instead of using separate options, they are now bundled into a newsetupoption.
The option takes a function as a value, so we can use the ES6 shorthand syntax and simply write it assetup(). Vue executes the function before the component is created, before any lifecycle hooks.
Two-way databinding with v-model
As an example, let’s log a message to the console insetup, as well as thecreatedandmountedhooks.
- The console output from the example above shows the order of execution.
- noteBecause setup is called so early in the lifecycle, the component hasn’t been initialized yet and this doesn’t reference the config object like we’re used to.
- We don’t use this in the setup option.
- To access data from the function in the components template, we return that data at the end of the setup option as an object (like we did with the data option).
- When a key has the same name as its value, we can use the ES6 shorthand syntax. noteThe data we returned above is not automatically reactive like it is in the data option.
We have to manually do it with reactive refs. If we want to make our returned data reactive, we use thereffunction. The function is imported from the ‘vue’ package and takes the data we want to make reactive as an argument.
If we want the data to be available in the template, we have to return thereffrom thesetupoption (like we do with thedataoption). If we want to access the value of arefinside thesetupoption, we have to use thevalueproperty. As an example, let’s create arefwith a simple greeting message that we return and output in the template. We’ll also access the value in a timer inside setup and change its value after 3 seconds. Arefdoesn’t have to be a primitive value, like a string or a number.
We can use objects as well. If we want to access it insidesetup, we have to use thevalueproperty again, followed by the object’s key.
If we expose the object’s properties outside of the setup option, they lose their reactivity.
They will display fine in the template, but they won’t update when the timer executes. We have to expose the whole object, not the separate properties. As mentioned earlier,refcreates a wrapper object when we pass single primitive values to it.
Thereactivefunction is likerefbut it can only take objects, not primitives. One benefit ofreactiveis that we don’t need to use thevalueproperty to access the object’s value. Butrefhas thevalueproperty for reassignment,reactivedoesn’t and therefore cannot be reassigned.
As we mentioned earlier,reactivecan only receive objects and cannot be reassigned so it’s use is limited. Butrefcallsreactivein the background, so in some cases you might want to avoid the overhead from the extra step and usereactiveinstead ofref. When you have primitive values (number, boolean, string etc.).
When you have an object you need to reassign later (like swapping an array for another). When you have an object you won’t need to reassign and you want to avoid overhead ofref. We userefexclusively simply because sometimes usingvalueand sometimes not can be confusing. We prefer the consistency of always usingref. Many other developers also prefer only using ref, and some even considerreactiveto beharmful.
Custom events and context
With the Options API we define custom functions in an option calledmethods.
Like data, we have to return a function from thesetupoption if we want it to be available in the template. As an example, let’s create three functions that change the value of arefwhen the button they’re bound to is clicked.
With the Options API we define computed properties in an option calledcomputed. With the Composition API, we define computed properties with thecomputedfunction.
The function is imported from the ‘vue’ package and takes a callback function as an argument. As an example, let’s take a first and last name from inputs in the template, then combine them in the computed function and output it to the template.
noteFrom the example above we also can see that event listening stays exactly the same as with the Options API. It’s only the way we implement computed properties that change. Two-way databinding withv-modelworks the same as before, except now we use arefinstead of a data property. With the Options API we define watchers in an option calledwatch. With the Composition API, we define watchers with thewatchfunction. The function is imported from the ‘vue’ package and takes two arguments. The data we want to watch. A callback function that can accept thenewValueandoldValuearguments. Instead of defining a named function in the option, we definewatchand do the watching in an anonymous or arrow function.
As an example, let’s take a message from an input in the template and watch for those changes with thewatchfunction. Like thewatchoption, if we want to run the watcher on the initial value as well, we can specifyimmediateto be true as an optional third argument.
Replacing the watch option with watch()
If we want to watch multiple data sources, we can specify them in an array. When we do, thenewValueandoldValuealso become arrays asnewValuesandoldValues. If ourrefis an object instead of primitives, we have to use a getter callback function to accesss the value. ThewatchEffectfunction works the same aswatch, except for two things.
It runs immediately on the initial value, the same as whenimmediate:trueinwatch. It automatically tracks dependencies in its body, we don’t explicitly add them as arguments. It has to be imported from the ‘vue’ package and takes a callback function as its only argument. The data source’s value must be used in the callback function’s body in some way for Vue to be able to track it. As an example, let’s take a message from an input in the template and log it to the console in thewatchEffectfunction.
With the Options API we define props when we invoke a component in its parent’s template block.
- In the child component we capture the props in thepropsoption of the config object. We can then use them in the child component either in the template with data binding, or in something like a computed property.
- When we use them in a computed property, we access the prop with thethiskeyword. But as mentioned earlier, we can’t usethisinsetup.
Replacing the computed option with computed()
At the start of the lesson we mentioned the setup function has two optional parameters, one of which is apropsobject. Instead ofthis, we use the object to access props with dot notation. To demonstrate, we will do a full example with the root App component as our parent component and the following new component.
The project should look similar to the following. The root App component takes a first and last name from inputs in the template and passes them to theGreetingMessagecomponent.
TheGreetingMessagecomponent takes the two name props and combines them into a full name with a computed property.
If we go to the browser and enter a first and last name in the input fields, the full name from the computed property will show. With the Options API we define an event in theemitsoption of a child component, then send it to a parent component with the$emitinstance function.
Replacing the methods option with functions
The parent listens to the event with event binding on the child component. We can then specify some sort of functionality to be executed when the event is captured, like changing a data property. In the Composition API we use the second of the two optional parameters in the setup option,context.
Replacing the data option with ref()
To demonstrate, let’s create a new component that will emit an event to the root App component. The project should look similar to the following.
TheMainMenuchild component will emit an event when the user clicks on a button. noteThepropsparameter doesn’t have a default value, so we have to include it even if we don’t use it.
In the root App component, we listen for the event and change arefwhen it fires. Therefis used to determine if the component is shown or not. With the Options API, we specify data we want to provide to another component in theprovideoption.
Once the data has been provided, we can inject it in the component where we want to use it with theinjectoption.
- Example: src/component/GreetingMessage.vue (receiving component). In the Composition API we use theprovidefunction to send data. This function must be imported from the ‘vue’ package and takes the key:value pair we want to provide as first and second arguments.
- To receive data, we use theinjectfunction. This function must also be imported from the ‘vue’ package and takes the provided key as an argument.
- As an example, we’ll provide ausernamewith a value of “John” from our root App component, which also imports and uses theGreetingMessagecomponent.
- Then, we’ll inject theusernameinto aGreetingMessagecomponent and store it in a constant.
Subscribe on herohero for weekly coding examples, hacks and tips
We’ll return the constant and output the value in the template. Example: GreetingMessage.vue (receiving component).
- When we run the example in the browser, it will show theusernamein theGreetingMessagecomponent. With the Options API we define lifecycle hooks as options in the config object.
- While this is still a perfectly valid approach, Vue gives us lifecycle functions that we can invoke inside the setup option.
- We can translate a lifecycle hook to its function counterpart by prefixing it with on. The following table shows lifecycle hooks in the Options and Composition APIs.
- noteThebeforeCreateandcreatedlifecycle hooks are not used because thesetupoption already runs before the component is created. Any functionality we need at the component’s creation can be done insidesetup.
Options API (regular architecture)
Lifecycle functions aren’t available by default. We need to import the ones we want to use from the ‘vue’ package.
For more information on the topics covered in this lesson, please see the relevant section below.
Modified6 months ago. Reading the composition api documentation for Vue 3, I didn't quite understand how the new Composition API works.
Could you explain please where data() function has gone and if it is no longer used what to use instead?
Updated 23.10.2021: The documentation in the link has been updated and expanded to include a mention of the data() in the Composition API introduction, so this question is now deprecated.
11 gold badge33 silver badges1111 bronze badges. 1111 bronze badges. Under the new Composition API, all of the variables that you previously defined in data() are just returned from your setup() function as normal variables with reactive values.
For example, a Vue 2.0 component that had a data function like so:. becomes this setup() function in Vue 3:. The ref helper wraps a non-object value for reactivity, and reactive wraps an object.
This is exposing the underlying principles of Vue more clearly than the old way, where the wrapping happened "magically" behind the scenes, but will behave the same otherwise. What I like about it personally is that your setup() function can build up your object on the go while keeping related things together, allowing it to tell a cohesive story and not require jumping around to different sections. 11 gold badge1616 silver badges2929 bronze badges. 2929 bronze badges. The composition is the new feature comes with Vue 3 and as a plugin for Vue 2, it doesn't replace the old option api but they could be used together in the same component.
The composition api compared to option api :. Gather the logic functionalities into reusable pieces of logic.
Use one option which the setup function which is executed before the component is created, once the props are resolved, and serves as the entry point for composition API's.
In Vue.js 2, the Options API was used and even still using, and now in Vue.js 3, we face the Composition API concept. To briefly explain why such a change has been made;.
Vue.js 2 left us having to use reactive variables (data), methods, and calculated values (computed) in one place. There was no easy solution to deconstructing the common logic between components.
Mixin was used to solve this, but they are quite complex. As the use of mixin increases, the definitions we make in components are mixed.
For these reasons, a different concept has been put forward in Vue.js 3. Of course, it has its shortcomings. But it has made us code reusability, its intelligibility simpler. Let’s go from slow to Composition API concept. First, the setup()the method was created for us to use the Composition API. A component option that is executed before the component is created, once they props are resolved. It serves as the entry point for composition APIs.
One of the important points is that you should not use the keyword thisin setup().
Because setupis called before data, computed, or methods are resolved. Let me tell you about the example I made. I’m pulling data from a service used on Vue’s own site. The data he used was written with the Options API. I wanted to use it with the Composition API. As you can see in the example I prepared, I created the isStatusproperty in data().
I’ll use it to show the data later. It will give you a setup()suggestion when you set the IDE you are using, and it will set it as it should. I want to explain the first concept I used setup()and similar concepts. I created data that I use, with ref(). Before using refwe need to import the package.