Composition API: a Quick overVue

Rate this content
Bookmark

Composition API is one of the biggest new features in Vue 3. In this talk, I will explain what is it and how to use Composition API for code abstraction and reuse.

28 min
18 Jun, 2021

Video Summary and Transcription

The Talk introduces the composition API in Vue 3 as a better option for composing reusable features compared to mixins and scope slots. It explains how to abstract search functionality using the composition API and demonstrates the creation of searchQuery and searchResultsQuery objects. The Talk also covers running breed search in the mounted hook, sorting results using computed properties, and the benefits of the composition API in terms of code organization and reusability. It concludes by mentioning the upcoming release of Vue 3 and the advantages of the composition API.

1. Introduction to Vue 3 Composition API

Short description:

Today we are going to speak about one important feature of Vue 3, which is a composition API. The new composition API is purely additive, so you won't need to rewrite all your components written with the Options API.

Hi everyone! Today we are going to speak about one important feature of Vue 3 will bring, which is a composition API. But before we start speaking about it, I want to give you an important warning. When we first introduced this new API, we made a huge mistake. We were speaking about deprecating some options from the old API and people understood it slightly differently than we want. You can see some quotes from Reddit saying like, do I need to write all my components to the new syntax? And I want to say, no, please don't be like this. The new composition API is purely additive. You won't need to write all your good components written with Options API to this new syntax.

2. The Need for a New Vue.js API

Short description:

After introducing myself as Natalia, a Vue.js core team member and front-end engineer at GitLab, I explained the need for a new API in Vue.js version 3. Using the example of CatSplorer, an app for searching and sorting cat breeds, I showed how the current code is fragmented and difficult to maintain. I then introduced mixings as a way to compose reusable features, but highlighted their limitations in terms of reusability and customization.

And after this warning, now I'm safe and I can introduce myself. My name is Natalia and I'm Vue.js core team member. I care mostly about Vue documentation. I work as a staff front end engineer at GitLab, and I'm also a Google Developer expert in web technologies.

So why do we need this new API? Is there anything we were really lacking in Vue.js version 2? Let's take a look at this small application. Please meet CatSplorer, an app to search and sort cat breeds. As you can see, we have two features here. First is searching. Second is sorting with different parameters.

In the application code, this will look like this. So, this code belongs to search. We have some part of the reactive state responsible for searching, and we have a method to run this search. And of course we have something for sorting. Again, we have some reactive data, and we have some computed properties to calculate these sorted results.

If we take a look at the component code, we will see how these two features are divided in it. So here is a code that belongs to search, and here is a code for sorting. And as you can see, the logic is pretty much fragmented here. Imagine I'm a developer who needs to fix the search, and I need to follow this logic and I will be jumping from data to method and vice versa. So do we have a way to compose this reusable features and abstract them somehow?

So the first option in the current API are mixings. Mixing is an object that can contain any set of component properties like data methods, computed lifecycle hooks. And when mixing is included into the component, these properties are mixed in with component properties. Sometimes component can override mixing properties if the there is a name collision. Sometimes they are merged together like in the case of lifecycle hooks. But basically you need to understand there's just mixing in properties from mixing to the components. So here is a mixing for the search, and here is a sorting mixing that includes only properties we need for sorting. And if we take a look at this, this is way less fragmented, right? And then we just include this mixing as a component at the bottom. But there are some problems about mixing. First of all, they're not really reusable. If you did pay attention to the search mixing, you saw this access call. So we are not able to customize our search.

3. Abstracting Search to Composition API

Short description:

We cannot pass the endpoint to the mixing and replacing Axios with CraftQL calls is conflict prone. Mixing properties can be overwritten by component ones, making it hard to track their source. Another option is scope slots, which allow child components to expose their scope to content in the slot. However, data and methods exposed to the scope slot can only be used within it, making it less flexible and performant. Vue 3 introduces the composition API as a better option, and we will demonstrate how to abstract these features into it.

We will always use the same endpoint because this is defined in the mixing. We cannot pass even the endpoint there, not speaking about replacing about replacing Axios with some kind of CraftQL calls. Conflict prone.

As I mentioned, mixing properties could be overwritten by component ones. In this case, we can't be sure that everything we exposed from the mixing safely landed in the component and unclear source. If you've ever used mixins, you know how hard it's to track which method comes from which mixing, especially if you have multiple swarms, multiple ones in the component.

We have another option, which is scope slots. I won't go into deep details, but basically in view, component can have slots, and we can place anything in this slot, like text, HTML, other components, and all this content will belong to parent scope. When we speak about scope slots, we mean that child component, in this case, it's generic search, can expose a part of its scope like a data, methods, whatever we want, to the content in the slot. So you can think about component with a scope slot, like a component that contains some logic, not a template in this case, like a wrapper that forms some operations and exposes data and methods to its content.

It looks much better because as you can see, we can pass run breed search there. So we are not setting it up to static access call, but this is not flexible. First of all, data methods that are exposed to the scope slot are exposed only to the scope slot. We cannot reuse any kind of exposed data in other places in the template or in the options API or whatever else outside of the slot, and this is less performant because in this case generic search is still a view component. This is a view instance and you need to mount this view instance to make it work. So do we have any other options in Vue 3? Yes. This is a new composition API, and I want to show you how does it work and how we can abstract these two features into the composition API. That's why we're switching to live demo. Wish me some luck.

So here is a code for the search and sorting, and let's start with abstracting search to its own composable. Let's go to composables folder and create a new file named search.js. And we want to export a function from here. Let's name it useSearch. And let's take a look. What do we have for search? First of all, we have two of these reactive properties, which are query and results. And we want to abstract them completely from this component. So let's create our first reactive property called searchQuery. And this will be a ref of an empty string. Empty string is an initial value of this search query here, and what ref does under the hood. In fact, we are creating a search query, which will be equal to an object with value of an empty string.

4. Creating SearchQuery and SearchResultsQuery

Short description:

This part explains how the searchQuery and searchResultsQuery objects are created using the ref function. The runBreedSearch method is introduced as a way to abstract the logic of the API call. It accepts a function as a parameter and calls it with the query value. The response is then used to set the value of search results.

And this object is reactive, thanks to ref. So any changes to searchQuery.value will be reactive. We need also to create a searchResultsQuery, which is a ref of an empty array. And of course we need some method. Let's call it runBreedSearch. And this, I'm sorry, my typing is really bad today. And this is a function. And what do we want to do here? So we want to pass something to run because we don't want to make this access call static, we want to abstract the logic. So this code will accept some function, let's say getResults. And it will call getResults. And we want to have our query as a parameter here. But remember, this is a ref. So when we are referring to the ref inside of the composition function, we need to remember about value. And then we have some response and we want to set search results value to this response.

5. Running Breed Search in Mounted Hook

Short description:

We want to run breed search in the mounted hook. We return search query, search results, and run breed search from the composition function. The setup option is introduced, allowing access to the setup's returned values in both templates and the options API. However, data properties and computed cannot be referred to in the setup. The use search method is used, passing a callback and recalculating the endpoint based on the query. Finally, the breed search, breed endpoint, and methods and mounted section are removed.

What else do we have for search? We abstracted on breed search. Oh, we have mounted. So we want to run breed search in mounted hook. This can be also abstracted here. And we want to run, run breed search. That's basically it. That's basically it.

Now we need to return whatever we want to use in the component from the composition function. So we're returning search query and search results in this case. And of course we need to return run breed search. Now we can start using this in the component. First, obviously we need to import our use search. From the composables.

And now we're introducing a new option in the component which is setup. In terms of life cycle hooks, setup will be involved before created hook. And we can access the things returned from the setup in both the templates and options API. So here, but we can't refer to data properties or compute it in the setup because when setup is running, we don't have data or computed. So let's use our use search method here. I want to have search query, search results, and run breed search here. And I need to pass a method here like a callback. So this callback will accept a query parameter, we're passing it here from search query value. And we need to recalculate endpoint. We cannot refer to this computed because setup is running before computed exist. So I will simply calculate it based on query. And then I want to run my access call. Here I will simply use an endpoint I've just defined. Here we should use our best query from search query value. And in a response I just want to filter data because saving logic will go to the composable. Now I can get rid of breed search, breed endpoint, and the whole methods and mounted section. And I need to fix my templates slightly.

6. Working on Sorting and Selected Option Index

Short description:

So this should be fine. We have our cats. Let's try the search. Great, search is abstracted. Now, let's work on sorting. We need options, active property, results, items, selected option index, and sorted results.

So this should be fine. And we also have these breed search results. This will be replaced the search results. Important moment. You can see I'm not using search results value here as well as I'm not using search query value here because when you use anything returned from the setup in the template or options API, ref will be automatically unwrapped for you. You don't need to care about value in the template.

So let's take a look at our application. And this all happened because I simply forgot to return everything from the setup. And trust me, I do this every single time. And I believe this is one of the cons of the new API because you need to explicitly return everything from the setup option. Here we go. And now, as you can see, we have our cats. Let's try to see if search works. It does. We didn't break sorting. No, we didn't. So, great, search is abstracted.

Now, let's try to work on sorting. I will create one more file. In fact, you can store all your composables in one file, but I just want to make it more visible. And I want to export function, use sorting here. So, what do we need for sorting? Let's try to take a look. First of all, we have options, and I don't want to hard-code them to sorting, I just want to pass them there. We have our active property for selected option, and this makes sense to be abstracted because this is an internal logic of sorting. And we have results. Obviously, results should be in sorting as well. But as you can see, we are sorting some items, and I don't want these items to be hard-coded, again, I just want to pass them to sorting. So we want to have our options and items. And we need to create selected option index, which is a reactive property with a default value of zero. And we need our sorted results.

7. Sorting Results with Computed

Short description:

As you can see, sorted results are computed property and will be recalculated if their reactive dependency changes. We can use computed in the composition API by importing them from the view. The logic is copied and slightly fixed. We don't have results sorting, only options, selected, and selected option index values. We use items as a trick by passing a computed property, and we return selected option index and sorted results from the setup option.

As you can see, sorted results are computed property, which means they will be recalculated if their reactive dependency change. We can use computed in the composition API as well. We just need to import them from the view. And in this case, computed will accept a callback. I will copy paste the logic from here and fix it slightly.

We don't have results sorting, we just have options. We have our selected, we have our selected option index value. Don't forget this is a ref. And here we will use our items. Here is a trick. I know I will pass a computed property as items here and computed is a ref internally. So here I will need to use items value. And I need to return everything I want from date sorting. So selected option index and sorted result. Oh God. Sorted results.

Now let's go back and try to change our component as well. First of all, I want abstract options to a small constant, let's call it sorting options. And I need to return these options from the setup as well, because I will use them in the template. Now let's import our used sorting from our Composables. And let's create more constants here. So we will have selected option index and sorted results from use search. And I will just move a constant declaration a bit higher because I will need it in my use sorting. So first parameter is sorting options. And second, as I already mentioned, is computed because I need to track any changes in my search results. And when they change, I want to recalculate this computed. In this case, I will return search results value. Remember, search results is a ref itself. And I want to return selected option index as well as sorted results from my setup option. I can remove data now as well as computed, and I need to change my template as well.

8. Sorting and Selected Option Index

Short description:

Here we will have sorting and selected option index. Sorting and search are working. Composition API can be used independently or in combination with the options API. Follow the link or Google Composition API RFC for more information. Check out the repository with starting and finished code. Thanks for joining us and for the positive feedback.

So here I will have sorting, oh god. Sorry, I'm really bad when I'm typing something when do live coding. And here we will have selected option index.

So let's take a look at the application again. Oh, of course, order by is not defined because I forgot to move this part of the logic from the template to the composable. And right now we fixed it, sorting works. Search works. Great, just a few mistakes during live coding and we are here.

So basically we just learned we can use Composition API independently. I read on the whole component or in the combination with a old good options API as well. If you want to learn a bit more about the Composition API, please follow this link or just Google for Composition API RFC. There is the most full source of information about the Composition API so far. And I also created this small repository you can play with. Please target view three branches. There is a branch with a starting code and with a finished code as well. And thank you.

Hey Natalia. Thanks for joining us and for this really clear talk. First comments. I actually got a message while you were speaking from a colleague of mine. Hey Dean, how are you doing? That he was thought, he has such a relaxed voice and that really helped him follow along. So he was in the moment with you. So this is something given. So I don't know if you can thank him for it, but yeah, he liked it. So, so did I, by the way.

I want to remind everyone that if I don't have time to answer your quest or ask questions to Natalia. Natalia will go to a Zoom room where you can continue to discussion about the Composition API or anything else future related with Natalia. And the link is below the player on the website in the timeline. You can just click on her Zoom room. Let's go to the first question and it's an easy one.

9. Benefits of Composition API

Short description:

The composition API is not recommended if you don't have features to abstract and reuse, or if your team is already familiar with the option API. However, you can evaluate the features that need to be reused and gradually add them with the composition API. The new composition API in Vue 3 allows you to combine logical code in one place, similar to React hooks, and create custom hooks for reusability. It also simplifies the development of Vue plugins by allowing you to export functions and use provide inject within the Vue instance.

It's from Amir Kubal. By the way, which font are you using? It looks so nice to me. It's Dank Mono font. Used together with Night Owls theme for VS code. Ah, nice. Dank Mono, that's from the guy from Formidable, right? It's a free font. Yeah, nice. No, this is not, unfortunately it's not. Oh, well. Maybe you have to sometimes pay money to use nice stuff. That's weird.

Next question is from Jan. When do you recommend not to use composition? No, as a part of the team that developed composition API, it's very tempting to say just use it everywhere. But in fact, if you, first of all, do not have features to abstract and reuse, and second, if you have a team that already get used to the option API, there is no reason to jump immediately and rewrite everything to composition API. You can evaluate features that need to be reused, and then you can iteratively add them with a composition API. So there's no like a law when to do it. You can always, but it depends on the project, basically, yeah.

Next question is from Ibrahim Beklieff. Which problems does a new composition API solve exactly? If I got it right, it helps to combine logical one thing and place it in one place, like what the React team did when they introduced the React hooks and give opportunity to create custom hooks like useSearch, useSort, et cetera. Yes. You basically get it right. Unfortunately in Vue 2, we lacked a tool to reuse logic, not components. As I mentioned, we could have mixins or scope slot, but still it was a very synthetic thing. And also composition API is very helpful in the case of writing Vue plug-ins for Vue 3. Because currently, if you are author of the library, you would need to work with a Vue instance and extend the Vue prototype. With composition API, it's much easier to do so because you can just simply export functions you created in the plugin and use provide inject within the Vue instance. So basically it's feature reuse and plugin development.

Okay, I hope that gives Ibrahim the complete answer he's looking for. Else he can find you in the Zoom Room.

10. Vue 3 Release and Composition API Advantages

Short description:

The release candidate for Vue 3 will be out very soon. The composition API in Vue offers advantages similar to React hooks but is custom and not built-in. When deciding which arguments to use as refs or plain values in custom composition functions, consider the need for reactivity.

Else he can find you in the Zoom Room. Next question is from O. Beresford. Is there a guess on when the Vue 3 will be out of beta status? I use Vue 2, and I've been pulling out extra slash non-Vue code via traditional means via SRP for SRP. As you probably understand, I have no allowance to say a certain date, even though we have it in mind. But release candidate is coming very soon, like really very soon. You will be surprised how soon it is. So can I like set an alarm now? Will it make the weekend? Give us a glimpse, Natali. No way, no way. Aw, damn it. Okay, well, good that you're tough on us.

Next question is from Poltermouth30. What advantages does the composition API offer against React hooks? Honestly, it's a bit complex to answer because the question is like, what advantages Vue offers over React, basically? Because they solve similar tasks but different frameworks. Basically, if you work with React for simplicity, you can consider composition API being kind of hooks for Vue. But the only thing is like, someone mentioned custom hooks. Like all composition APIs are custom, we don't have built-in composition APIs. Yeah, okay. So it's apples and oranges. Then closer to each other even.

Okay, another question from Andrew Green H. How do you decide which arguments for your custom composition functions are supposed to be refs and which should be plain values? Basically, if you need reactive value, these should be always ref. You probably noticed that I'm passing options that is static because I didn't plan to change these options in my application. This is just a constant. And this shouldn't be a ref or reactive. If you plan to react on the change of this parameter, this should be always a ref or computed like I did passing a parameter to the sorting option. If we speak about comparison with Vue 2, you can think that non-reactive values if you pass them as non-reactive, is a some function like dollar sign options. If you want something reactive, like from data or computed, they should always be ref or computed.

Okay, I think that's all the time we have for the live Q&A, but I'll just mention once again, if you want to know more about the competition API, please go to the Zoom room. It's in the link. The link is in the timetable below us in the player. There's a timeline below. So there's a new question coming in right now and we're not gonna answer it. So Suwy, will have to go to the Zoom room unfortunately, and we're gonna go to the next speaker. Natalia, thanks a lot for joining us all the way from Ukraine here in Amsterdam, kind of. Thank you. And thanks a lot for being here.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Vue.js London Live 2021Vue.js London Live 2021
34 min
Everything Beyond State Management in Stores with Pinia
Top Content
When we think about Vuex, Pinia, or stores in general we often think about state management and the Flux patterns but not only do stores not always follow the Flux pattern, there is so much more about stores that make them worth using! Plugins, Devtools, server-side rendering, TypeScript integrations... Let's dive into everything beyond state management with Pinia with practical examples about plugins and Devtools to get the most out of your stores.
Vue.js London Live 2021Vue.js London Live 2021
20 min
One Year Into Vue 3
Top Content
Vue 3 may still sound new to many users, but it's actually been released for over a year already. How did Vue 3 evolve during this period? Why did it take so long for the ecosystem to catch up? What did we learn from this process? What's coming next? We will discuss these questions in this talk!
Vue.js London Live 2021Vue.js London Live 2021
8 min
Utilising Rust from Vue with WebAssembly
Top Content
Rust is a new language for writing high-performance code, that can be compiled to WebAssembly, and run within the browser. In this talk you will be taken through how you can integrate Rust, within a Vue application, in a way that's painless and easy. With examples on how to interact with Rust from JavaScript, and some of the gotchas to be aware of.
Vue.js London Live 2021Vue.js London Live 2021
24 min
Local State and Server Cache: Finding a Balance
Top Content
How many times did you implement the same flow in your application: check, if data is already fetched from the server, if yes - render the data, if not - fetch this data and then render it? I think I've done it more than ten times myself and I've seen the question about this flow more than fifty times. Unfortunately, our go-to state management library, Vuex, doesn't provide any solution for this.For GraphQL-based application, there was an alternative to use Apollo client that provided tools for working with the cache. But what if you use REST? Luckily, now we have a Vue alternative to a react-query library that provides a nice solution for working with server cache. In this talk, I will explain the distinction between local application state and local server cache and do some live coding to show how to work with the latter.

Workshops on related topic

Vue.js London Live 2021Vue.js London Live 2021
169 min
Vue3: Modern Frontend App Development
Top Content
Featured WorkshopFree
The Vue3 has been released in mid-2020. Besides many improvements and optimizations, the main feature of Vue3 brings is the Composition API – a new way to write and reuse reactive code. Let's learn more about how to use Composition API efficiently.

Besides core Vue3 features we'll explain examples of how to use popular libraries with Vue3.

Table of contents:
- Introduction to Vue3
- Composition API
- Core libraries
- Vue3 ecosystem

Prerequisites:
IDE of choice (Inellij or VSC) installed
Nodejs + NPM
Vue.js London Live 2021Vue.js London Live 2021
117 min
Using Nitro – Building an App with the Latest Nuxt Rendering Engine
Top Content
Workshop
We'll build a Nuxt project together from scratch using Nitro, the new Nuxt rendering engine, and Nuxt Bridge. We'll explore some of the ways that you can use and deploy Nitro, whilst building a application together with some of the real-world constraints you'd face when deploying an app for your enterprise. Along the way, fire your questions at me and I'll do my best to answer them.
JSNation 2022JSNation 2022
141 min
Going on an adventure with Nuxt 3, Motion UI and Azure
WorkshopFree
We love easily created and deployed web applications! So, let’s see what a very current tech stack like Nuxt 3, Motion UI and Azure Static Web Apps can do for us. It could very well be a golden trio in modern day web development. Or it could be a fire pit of bugs and errors. Either way it will be a learning adventure for us all. Nuxt 3 has been released just a few months ago, and we cannot wait any longer to explore its new features like its acceptance of Vue 3 and the Nitro Engine. We add a bit of pizzazz to our application with the Sass library Motion UI, because static design is out, and animations are in again.Our driving power of the stack will be Azure. Azure static web apps are new, close to production and a nifty and quick way for developers to deploy their websites. So of course, we must try this out.With some sprinkled Azure Functions on top, we will explore what web development in 2022 can do.
Vue.js London 2023Vue.js London 2023
137 min
TresJS create 3D experiences declaratively with Vue Components
Workshop
- Intro 3D - Intro WebGL- ThreeJS- Why TresJS- Installation or Stackblitz setup - Core Basics- Setting up the Canvas- Scene- Camera- Adding an object- Geometries- Arguments- Props- Slots- The Loop- UseRenderLoop composable- Before and After rendering callbacks- Basic Animations- Materials- Basic Material- Normal Material- Toon Material- Lambert Material- Standard and Physical Material- Metalness, roughness - Lights- AmbientLight- DirectionalLight- PointLights- Shadows- Textures- Loading textures with useTextures- Tips and tricks- Misc- Orbit Controls- Loading models with Cientos- Debugging your scene- Performance
Vue.js London Live 2021Vue.js London Live 2021
176 min
Building Vue forms with VeeValidate
Workshop
In this workshop, you will learn how to use vee-validate to handle form validation, manage form values and handle submissions effectively. We will start from the basics with a simple login form all the way to using the composition API and building repeatable and multistep forms.

Table of contents:
- Introduction to vee-validate
- Building a basic form with vee-validate components
- Handling validation and form submissions
- Building validatable input components with the composition API
- Field Arrays and repeatable inputs
- Building a multistep form
Prerequisites:
VSCode setup and an empty Vite + Vue project.
Vue.js London Live 2021Vue.js London Live 2021
116 min
Building full-stack GraphQL applications with Hasura and Vue 3
Workshop
The frontend ecosystem moves at a breakneck pace. This workshop is intended to equip participants with an understanding of the state of the Vue 3 + GraphQL ecosystem, exploring that ecosystem – hands on, and through the lens of full-stack application development.

Table of contents
- Participants will use Hasura to build out a realtime GraphQL API backed Postgres. Together we'll walk through consuming it from a frontend and making the front-end reactive, subscribed to data changes.
- Additionally, we will look at commonly-used tools in the Vue GraphQL stack (such as Apollo Client and Urql), discuss some lesser-known alternatives, and touch on problems frequently encountered when starting out.
- Multiple patterns for managing stateful data and their tradeoffs will be outlined during the workshop, and a basic implementation for each pattern discussed will be shown.
Workshop level

NOTE: No prior experience with GraphQL is necessary, but may be helpful to aid understanding. The fundamentals will be covered.