Modern State Management with Vue 3

This ad is not shown to multipass and full ticket holders
React Summit US
React Summit US 2025
November 18 - 21, 2025
New York, US & Online
The biggest React conference in the US
Learn More
In partnership with Focus Reactive
Upcoming event
React Summit US 2025
React Summit US 2025
November 18 - 21, 2025. New York, US & Online
Learn more
Bookmark
Rate this content

The Vue 3 Reactivity and Composition API offers developers flexible techniques to work with reactive data. They enable a new and modern approach to handling State Management. Developers can now effortlessly implement local and global stores. Vuex has been one of the most used First-party plugins for Vue 2. Let's have a look at the advantages and tradeoffs of using Composables instead of Vuex.

This talk has been presented at Vue.js London Live 2021, check out the latest edition of this JavaScript Conference.

FAQ

Vanessa is responsible for the front end at Cevy and co-hosts two podcasts: Expect Exception and Working Draft.

Vue 3 is a modern JavaScript framework used for building user interfaces. It introduces the Composition API, which allows developers to encapsulate logical units and manage state more effectively.

The key APIs in Vue 3 are the Options API, Reactivity API, and Composition API. These APIs provide various functionalities for building and managing components and state in Vue applications.

The Composition API in Vue 3 allows developers to encapsulate logical units within a setup function, providing a more modular and maintainable approach to building Vue components.

Yes, you can use Vue 3 without the Options API and Vuex by leveraging the Composition API, which provides powerful tools for managing state and logic within components.

In Vue 3, ref is used to create a reactive reference to a value, while reactive is used to create a reactive object. Developers can choose between them based on their preference and the specific requirements of their application.

The Composition API allows developers to group related logic together, making the code more modular and easier to maintain. This is achieved by encapsulating related functionalities within composable functions.

Composables are reusable functions that encapsulate related logic and state using the Composition API. They can be used across different components to share functionality.

State management in Vue 3 can be achieved using composables, which allow developers to create and manage global state using reactive references and computed properties.

The provide and inject pattern in Vue allows parent components to provide values that can be injected into child components, enabling a way to share state and dependencies across components without prop drilling.

Vanessa Otto
Vanessa Otto
22 min
21 Oct, 2021

Comments

Sign in or register to post your comment.
Video Summary and Transcription
Vanessa introduces Vue Free and discusses the benefits of using the Composition API. The order of execution and grouping logical units using the Composition API is explained. The Composition API is used for state management and refactoring components. The speaker shares their initial experience with state management using Vuex. Composables are explored as an alternative for state management in Vue 3.

1. Introduction to Vue Free and the Composition API

Short description:

In this part, Vanessa introduces Vue Free, a powerful state management solution for Vue applications. She shares her journey of using Vue Free without Options API and Vuex, leveraging the Composition API instead. Vanessa explains the benefits of the Composition API and how it can be used in small applications. She also discusses the three APIs in Vue: options API, reactivity API, and composition API, highlighting the advantages of the composition API. Finally, she provides a recap of writing a component in Vue 2 or Vue 3 using the options API.

Hi, now we are going to talk about modern state management with Vue Free.

Hi, I'm Vanessa. You can find me online as Vanze. I'm responsible for the front end at Cevy. I'm co-host of two different podcasts, Expect Exception, where we talk about front-end testing and Working Draft, a German podcast about web development. And roughly a year ago, in September, 2020, I can remember as I sat there watching Avenu on the Vue JS conference, finally saying, hey, Vue Free is out there, and now I want you to go with me on the journey, how I installed Vue Free and used alternative concepts to use Vue Free completely without Options API and also without VueX. I do not suggest that you should use Vue Free without Options API or replace VueX. I want to tell you that the Composition API is so powerful that we actually can use Vue without both of those tools, and it made sense for me in a state where I had a really small application which I started with Vue Free from scratch and did not have to migrate from my Vue2 application.

In the code examples I will show in the next couple of minutes, I will use the set up function and I prefer to use ref over reactive. But everything I will show now you of course can use the script setup syntactic sugar instead and you can choose to use reactive instead of ref if you prefer to.

As my components of my very small Vue Free application roughly a year ago started to grow because I had some more complex problems which needed some more complex solutions, I and therefore also this talk were mainly inspired by those three articles. Group, extract share pattern, state management with composition API, and should you use composition API as a replacement for Vuex.

Let's focus on three of the Vue's APIs for now, the options API, reactivity API, and composition API. The options API, we can think of this object structure that we know from your two single file applications, single file components, where we have our data computed, methods, watch mounted, and many more. And the reactivity API is not that different of that. We have refReactive for reactive data computed, watch, watch effect, unmounted, and many more. But the clue is that I can now import those functions directly from Vue. I don't have to use a Vue single file component or a Mixon to use those tools. I can import them in any JavaScript or TypeScript file. And then the composition API is providing us with a setup function where I can bring all the magic together and use all of those powerful tools of the Reactivity API in my Vue component.

So let's have a recap of how to write a component in Vue 2 or in Vue 3 using the options. Here I have a template with a paragraph with greeting and full name. If I scroll down to my script block, I can see here that I have a data function, which is a turning an object with greeting and hello. I have properties for first name and last name. And I have a computed property for the full name, which is returning me a first name with a spice and the last name. So this is one component with just one purpose, which is doing its job quite well. Kind of a funny side note is that I initialized this greeting here as a reactive data attribute, although I actually don't ever change it and won't need this observers on it anyway. But I was never sure where to put this constants using the options API. The problem I now want to focus on is that logical units, if the component is growing and growing, are spread over the whole script block. So what do I mean with this? I've prepared this code sandbox here, and here we can see as well we have our greeting and full name to say hello to the user.

2. Order of Execution and Grouping Logical Units

Short description:

This part focuses on the order of how things are happening in the script block. It explains how the composition API enables developers to group logical units together in a single file or share them with others. The speaker shares their experience with the composition API and how it can be used without sharing functionality. They provide an example of a reimplementation of the greeting using the composition API, highlighting the simplicity and power of using JavaScript directly.

But then we also displayed the user's items where we loop over and also provide a delete item function to delete something. If I scroll down to the script block, I now want you to focus on the order of how things are happening. I have the data function which is running an object with the greeting and items. The properties having stuff from the greeting. A computed property with a full name of the greeting. Then a method with the function delete item of the items. The categories bind to the way that the view skeleton, the view object here is structured.

Everything in data is in data. Every computed property is in computed property. Every function is in the methods block. Now we have a point where we have now greeting items, greeting, greeting items. They are shattered over the whole file. This is kind of, it grows and grows and grows, looking like this. Of course it can be a solution to split the component, but let's focus on it doesn't work anymore, we can't split any further, and we still have this lines of code not really bind together and what the composition API is providing us with is a possibility to group logical units together again, so that everything is related to the greeting, we can imagine being in this light blue box on the top and everything related to the items we can imagine to be bind together in this darkish blue, almost black box here. So the composition API enables developers to encapsulate logical units in one single file or in shared with others.

What I mean with that as I learned about the composition API a year ago, it always was sold to me as this is the go to thing instead of mixing. Use the composition API to share functionality. It's really powerful. But then I started with U3, I thought, but do we really need to share logic to use the composition API? Because I really like how it works the composition API, and I actually like to use it also without sharing functionality. And this is exactly what we will do now. So I have created some Hello World files on this view single file component playground. And the first one is a reimplementation of the just the greeting stuff we saw beforehand in U3 composition API. So here we have a template with the greeting and full name. And we import computed from view. If I scroll down to the properties, I see the first name and the last name. And here below I have the setup function, which is giving me a constants greeting with Hello, and a full name with as a computed property, and then I return everything to give it over to my template. What is kind of cool is that it's just JavaScript, right? It feels good to me. Actually, it felt a bit sweat like the first time I see it, the first time I saw it. So here we have the cons greeting. It's just a pure cons without wrapping it in a data object, not using a created lifecycle hooked to initialized constants.

3. Composition API and State Management

Short description:

In this part, the speaker discusses using the composition API to group logical units and refactor components. They demonstrate how to encapsulate functionality in separate functions and return necessary properties. The use of ECMAScript destructuring is explored, along with the importance of explicit imports for better IDE support. The speaker also mentions the Vue Use Git repository as a resource for prewritten composables. They then transition to discussing state management, highlighting the drawbacks of props drilling and using the global root object in Vue 2.

Just a const, and when they have a full name as computed property. But of course, also here the functionality can grow a bit. We are switching to our Hello World 2 component, and where I have also my items, which I also can delete. I loop over them in the template and I have my method to delete them. I import computed and ref now from you, and if I now scroll down to the setup block, what we can see is the same implementation for greeting with a greeting and full name, and then a logical unit of the items and a method to delete the items.

And as I started with U3, all of the time my muscle memory was like, oh yeah, I have to put everything data related in the beginning, and then all over the computed properties and then all of the methods and then all of the lifecycle hooks until I remembered, no, no, no, I don't have to use this anymore. I can now bind the logical units. I can just put them together. But then of course my component was growing a bit and I was like, yeah, how do I actually say that this things belong together? Do we have a comment like start items block and items block? How do I achieve this? So I started to refactor this component a bit, the same template we saw before, but now on top we have two different functions, the use greeting and the use items, which encapsulate all of the functionality in those functions where I have everything related here and return the necessary properties to the outside. And if I scroll down to the setup block, I can now see that it's getting a bit more cleaner if it was getting a bit nasty and I can outsource all of this logic to somewhere else. And here I can clearly see the greeting and full name items and delete items coming from those two composables.

But now the next step is, Hey, it would be super amazing if I can use the use items also somewhere else, because I really need this functionality also at another component, which leads us to hello world four, which is also refactoring a bit further. I only import computed now again from you and not ref anymore, but now I also import use items from use items. Switching to this file I can see import ref from you on top in a plain JavaScript file and the same function with the use items which are just before is now an exported function file, bringing us all of the functionality as a composable in our view single file component. If I scroll down to the setup block I can see here again I have my use greeting and the use item. I want to give you a small hint what I'm doing here. So what you can see here is that I first thought it is super cool to use ECMAScript destructuring to get everything related to the use items directly into the template. One line of code, this looks super cool, but then a problem that occurred to me is that I don't have any IDE support here on this playground and if I try to look for the delete item, I'm lost. I don't know where it's coming from and therefore what I tend to do is really to go the explicit way to not use magic provided by a language by me, but really saying explicitly okay, I import those things from there and now I can see okay, the delete item is coming from the use items and the use items is coming from this file. So we already wrote our first composables. If you are looking for a bit more inspiration, check out this Vue Use Git repository where you can find a lot of in typescript prewritten composables that you can use, Axios functions and so on and so forth. I think it's also already Hektoberfest time, so also if you want to get engaged in open source, this could be a start point for you. Okay, but now let's focus on state management. So how did I thought state was working when I started with Vue 2 in 2017 or something like that. First I did the anti-pattern of props drilling. So I used props emit event handling to get something from root component to, it's really like rent rent rent rent rent rent rent children to just emit, emit, emit, emit everything up again. This was not really maintainable. Then I thought I'm smart and I used the global root, the dollar root to attach variables to this global root thing until I realized this is not working. This is not really reactive. I think I should really not use this.

4. Initial Experience with State Management and Vuex

Short description:

The speaker discusses their initial experience with state management and Vuex. They explain how installing Vuex simplified the process of creating state management and allowed them to focus on more complex aspects of development.

It was also not really discussed. It was just really hidden in the API documentation that there is something like a global root. And then I sat down and thought, okay, state management sounds important, sounds difficult. Store sounds difficult, observables, Vuex, I'm not sure, but I will install Vuex now. And it was really just mind blown how simple this made it for me to create state management by only creating this index.js file. And already I had some state. It was a really powerful tool because it was so simple to use to then focus on the complex parts of writing code or finding solutions for bigger problems.

5. Using Composables for State Management

Short description:

When starting with Vue 3, I realized I could achieve state management with composables. I wanted to explore the possibilities further. In a code sandbox example, I focused on cart items with a loading state and used the unmounted hook to fetch data. The setup function contained the state, load items function, and methods for deleting items. I then switched to a different alternative of the application, importing the use items composable in the cart items alternative. This approach provided local state management.

But when I was starting with Vue 3, I thought, hey, give me a second. I think I can do achieve state management actually with composable. And it was not because Vue wasn't ready for Vue 3 yet. They were pretty quick and there was a migration guide. But I was interested in what is everything I can actually achieve with composables. I want to get a step further here. And here I have another code sandbox, which will probably load soon. But I think I also have it preloaded here. Yes, I do.

So here I want to focus first on the cart items, which we see here. And now I have a bit more of a realistic example. So if I reload this, you can see that there will actually be like three seconds of a loading time because usually I fetch the items from a server. So I have three seconds of loading and then I see the items. And here I have a first item. So what I have to buy next are the eggs and then I have my list of items and here I really use now a state with a floating where I can set a loading state if it's still loading. And in the script part I additionally use now the unmounted hook where I can fetch the data. So going to the setup function we can now see the state with the items and the loading. And then I have the important function here are the load items where I set isLoading to true. Since I don't actually have a real endpoint that I can talk to I use a useSleep function for three seconds. And then I set some dummy items, my eggs and my milk. And if everything works out I can set isLoading to false again. I also have my method to delete the item and I have a computed property for the first item and I use the unmounted lifecycle hook to load the items as soon as my component has mounted.

Ok, so far so good, we have something looking like a state but it doesn't really feel like state management right away. So now I want to go to the app root component and switch to a different alternative of this application and use now two different components which are both providing us our items. So if I save this and reload, in the meantime I will go to the cart items alternative which is looking pretty similar to the favourites. So they are both just showing our items. So on the cart items alternative, I scroll down and instead of the whole logic we saw beforehand, I can now see that I import the use items composable and I get all of the necessary data from the state load items, first item, delete item and unmounted, I call the load items function. Now I can see here my three seconds loading and I can see two times my list for my items. And here I want you to focus on the local state management, if I open the file, which I thought I had opened before, but I do it again for the composable. I can now see that the state here is outside of the component of this export function.

6. Implementation and State Management

Short description:

The implementation is the same as before, with the addition of the read-only keyword to create a store-like feeling. The state can be placed inside the exported function, allowing for local state management. However, if global state management is desired, the state can be moved on top of the export. By exporting the function multiple times, the state is created only once and remains global. After installing the dependencies, the X can be deleted twice, demonstrating both loading and global state management.

And the rest of the implementation is the same one as before. It's just copied over with one important difference. So here I import additionally the read-only keyword by view to have this store-like of feeling of this composable, to have the single source of truth what we expect our store should behave like. And now I want to put the state inside of this exported function. And if I am doing this and wait for it to reload here. Ah, come on. They are loading for three seconds. And I have my x, which I can delete in those local state. And here below I can delete the fresh milk on those local state management as both the card items alternative and the favorites are both using this use items, which has the state initialized inside of this function. But if you think, hey, this is kind of weird. This is not what I expect from state management. I expect it to be global. This is achieved by just moving the state on top of the export. And I will reload this again. And then you can see that, therefore, I just created the state now once. It's no global. It doesn't change. We don't initialize it a couple of times. We just export this function a couple of times. So after I installed all of those dependencies, you will see that I can now delete the X and they will be deleted twice. So they are loading and global state management.

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

Everything Beyond State Management in Stores with Pinia
Vue.js London Live 2021Vue.js London Live 2021
34 min
Everything Beyond State Management in Stores with Pinia
Top Content
State management is not limited to complex applications and transitioning to a store offers significant benefits. Pinia is a centralized state management solution compatible with Vue 2 and Vue 3, providing advanced devtools support and extensibility with plugins. The core API of Pinia is similar to Vuex, but with a less verbose version of stores and powerful plugins. Pinia allows for easy state inspection, error handling, and testing. It is recommended to create one file per store for better organization and Pinia offers a more efficient performance compared to V-rex.
Using useEffect Effectively
React Advanced 2022React Advanced 2022
30 min
Using useEffect Effectively
Top Content
Today's Talk explores the use of the useEffect hook in React development, covering topics such as fetching data, handling race conditions and cleanup, and optimizing performance. It also discusses the correct use of useEffect in React 18, the distinction between Activity Effects and Action Effects, and the potential misuse of useEffect. The Talk highlights the benefits of using useQuery or SWR for data fetching, the problems with using useEffect for initializing global singletons, and the use of state machines for handling effects. The speaker also recommends exploring the beta React docs and using tools like the stately.ai editor for visualizing state machines.
React Query: It’s Time to Break up with your "Global State”!
React Summit Remote Edition 2020React Summit Remote Edition 2020
30 min
React Query: It’s Time to Break up with your "Global State”!
Top Content
Global state management and the challenges of placing server state in global state are discussed. React Query is introduced as a solution for handling asynchronous server state. The Talk demonstrates the process of extracting logic into custom hooks and fixing issues with state and fetching logic. Optimistic updates with mutation are showcased, along with the benefits of using React Query for data fetching and mutations. The future of global state management is discussed, along with user feedback on React Query. The Talk concludes with an invitation to explore React Query for server state management.
One Year Into Vue 3
Vue.js London Live 2021Vue.js London Live 2021
20 min
One Year Into Vue 3
Top Content
Vue 3 has seen significant adoption and improvements in performance, bundle size, architecture, and TypeScript integration. The ecosystem around Vue 3 is catching up, with new tools and frameworks being developed. The Vue.js.org documentation is undergoing a complete overhaul. PNIA is emerging as the go-to state management solution for Vue 3. The options API and composition API are both viable options in Vue 3, with the choice depending on factors such as complexity and familiarity with TypeScript. Vue 3 continues to support CDN installation and is recommended for new projects.
Vue: Feature Updates
Vue.js London 2023Vue.js London 2023
44 min
Vue: Feature Updates
Top Content
Watch video: Vue: Feature Updates
The Talk discusses the recent feature updates in Vue 3.3, focusing on script setup and TypeScript support. It covers improvements in defining props using imported types and complex types support. The introduction of generic components and reworked signatures for defined components provides more flexibility and better type support. Other features include automatic inference of runtime props, improved define emits and defined slots, and experimental features like reactive props destructure and define model. The Talk also mentions future plans for Vue, including stabilizing suspense and enhancing computer invalidations.
Jotai Atoms Are Just Functions
React Day Berlin 2022React Day Berlin 2022
22 min
Jotai Atoms Are Just Functions
Top Content
State management in React is a highly discussed topic with many libraries and solutions. Jotai is a new library based on atoms, which represent pieces of state. Atoms in Jotai are used to define state without holding values and can be used for global, semi-global, or local states. Jotai atoms are reusable definitions that are independent from React and can be used without React in an experimental library called Jotajsx.

Workshops on related topic

Rethinking Server State with React Query
React Summit 2020React Summit 2020
96 min
Rethinking Server State with React Query
Top Content
Featured Workshop
Tanner Linsley
Tanner Linsley
The distinction between server state and client state in our applications might be a new concept for some, but it is very important to understand when delivering a top-notch user experience. Server state comes with unique problems that often sneak into our applications surprise like:
- Sharing Data across apps- Caching & Persistence- Deduping Requests- Background Updates- Managing “Stale” Data- Pagination & Incremental fetching- Memory & Garbage Collection- Optimistic Updates
Traditional “Global State” managers pretend these challenges don’t exist and this ultimately results in developers building their own on-the-fly attempts to mitigate them.
In this workshop, we will build an application that exposes these issues, allows us to understand them better, and finally turn them from challenges into features using a library designed for managing server-state called React Query.
By the end of the workshop, you will have a better understanding of server state, client state, syncing asynchronous data (mouthful, I know), and React Query.
Vue3: Modern Frontend App Development
Vue.js London Live 2021Vue.js London Live 2021
169 min
Vue3: Modern Frontend App Development
Top Content
Workshop
Mikhail Kuznetsov
Mikhail Kuznetsov
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
Going on an adventure with Nuxt 3, Motion UI and Azure
JSNation 2022JSNation 2022
141 min
Going on an adventure with Nuxt 3, Motion UI and Azure
Workshop
Melanie de Leeuw
Melanie de Leeuw
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.
State Management in React with Context and Hooks
React Summit Remote Edition 2021React Summit Remote Edition 2021
71 min
State Management in React with Context and Hooks
Workshop
Roy Derks
Roy Derks
A lot has changed in the world of state management in React the last few years. Where Redux used to be the main library for this, the introduction of the React Context and Hook APIs has shaken things up. No longer do you need external libraries to handle both component and global state in your applications. In this workshop you'll learn the different approaches to state management in the post-Redux era of React, all based on Hooks! And as a bonus, we'll explore two upcoming state management libraries in the React ecosystem.
Building Vue forms with VeeValidate
Vue.js London Live 2021Vue.js London Live 2021
176 min
Building Vue forms with VeeValidate
Workshop
Abdelrahman Awad
Abdelrahman Awad
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.
Building full-stack GraphQL applications with Hasura and Vue 3
Vue.js London Live 2021Vue.js London Live 2021
115 min
Building full-stack GraphQL applications with Hasura and Vue 3
Workshop
Gavin Ray
Gavin Ray
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.