Vue3: Modern Frontend App Development

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

Rate this content
Bookmark
Video Summary and Transcription
The video explores the transformative features of Vue 3, emphasizing its Composition API, which enhances code organization and reusability through composable functions. This API is a key topic of the talk, highlighting its benefits in code decoupling and maintainability. The Vue 3 setup function is discussed, showcasing its role in initializing components and maintaining component lifecycle logic. The VueUse library is introduced as a valuable tool for developers, offering hooks that simplify common functionalities like CSS variable management and local storage interaction. The Provide/Inject feature in Vue 3 is explained, illustrating how it facilitates dependency injection and improves component reusability by avoiding prop drilling. The video also covers the migration from Vue 2 to Vue 3, highlighting tools like Vue Demi and the migration build that aid in a smooth transition by supporting both versions simultaneously and allowing gradual feature adoption.

FAQ

Vue 3 is the third version of the Vue.js framework, known for its progressive JavaScript capabilities. It introduces features like the Composition API, improved TypeScript support, and better performance through techniques like tree-shaking. Vue 3 also enhances modularity and provides tools like the migration build to help transition from Vue 2, ensuring backward compatibility and facilitating the adoption of new features gradually.

The Composition API in Vue 3 allows for better code organization and reuse by encapsulating logic into composable functions. This API makes the code more maintainable and testable by decoupling it from the components and promoting reuse of logic across different parts of your application. It supports TypeScript better, enabling more robust type-checking and enhancing developer productivity.

The VueUse library provides a collection of essential Composition API functions (referred to as hooks) that handle many common functionalities in Vue 3 projects, such as managing CSS variables, interacting with local storage, or detecting user actions. Using VueUse simplifies development, reduces boilerplate, and improves code readability and maintainability.

In Vue 3, the Provide/Inject feature allows for dependency injection, enabling a parent component to provide data or dependencies, which can then be injected into any descendant component in the component tree. This feature simplifies the component structure, avoids prop drilling, and enhances component reusability and maintainability.

For migrating from Vue 2 to Vue 3, developers can utilize the Vue Demi library for supporting both versions simultaneously in libraries or plugins, and the migration build which offers a compatibility build to gradually adopt Vue 3 features while ensuring the application remains functional. These tools help manage the transition smoothly by allowing incremental updates and testing.

1. Introduction and Workshop Overview#

Short description:

I'm Mikhail and I will be running today's workshop about Vue 3 features. We'll focus on the composition API and I'll showcase its benefits in a demo. I've been using Vue since version 1 and became a big fan. Follow me on Twitter for more Vue and front-end development content. Let's do a quick round of introductions to understand the audience's technical stack.

I'm Mikhail and I will be running today's workshop about view 3 features. I'm really happy to see a lot of messages in the chat. Great, great, guys. I see that you can hear me definitely, and hope you can see the picture clearly. So if along the way there are any disturbances with the video or sound quality, please let me know. That shouldn't happen normally, but we'll see. Cool.

So let's... I think it's enough time for people to join already, let's move on. So, what are we going to be talking about today? Mostly focusing on Vue 3, the third version. And I'll start with some basics introduction then I'll do a more deep dive into the Vue 3 features, mostly composition API, and then we'll go into demo mode, when I will be showcasing most of the items that composition api brings. Let me quickly introduce myself, Mikhail. I'm developing web for over a decade now. I currently work as a team lead at ING Bank in Amsterdam. I started first using Vue somewhere around 2016, when it was still version 1, and actually when Geiss released version 2, I was really fascinated how easy and composable it is to build complex web UIs. And also the ecosystem documentation, everything was really nice, so I became a really big fan of this framework. Since then, I've been using it in a lot of commercial and side projects as well.

You can follow me on Twitter. This is a hard to pronounce set of characters. So, please, if you can't write it down, I will type it in the chat. So, I'll be happy to answer your questions in the chat, here during the session, but also follow me on Twitter. I'll try to post some stuff related to Vue and front-end development once in a while.

Yeah. Let's also do a quick round of introduction. That will also help me to understand better the audience level and also serve like an introduction so we know the composition of today's participants. So, can you please write down in short sentence your technical stack, what other frameworks or libraries, languages you use daily. If you're still studying, it's also fine. Just it can be back and front and I don't know, web design, data science, whatever, just in one line, something like PHP, three years, that should work. So please share your current stack or the stack that you are interested in. If you're using vue, of course, it would be nice to know which version are you using mostly. So please I'll give about a minute for this and then we'll move on.

2. Introduction to Vue and Workshop Overview#

Short description:

Yeah, I hope you liked it. I'm really happy to present a workshop in this community. Vue is a community-driven, super successful open-source project with almost 200,000 stars on Github. It has a brilliant ecosystem of tools and is used a lot across the industry. Vue is steadily gaining popularity and is a great choice for any size of project. Give it a shot and you may also like it. A typical Vue component has logic and templates, where you can output data, bind events, and reuse parts or other components. The main part is in the JavaScript side, where you define properties, state variables, and use methods to mutate data. This is called the options API.

Yeah, I saw some first message. Thanks Robert. Switching from Angular. Oh, that's a very well known story for me. Yeah, I had the same challenge some years ago. Yeah, I think you'll find a lot of similar concepts and yeah, definitely the way you can compose components and reuse logic, you should definitely like it. So I hope you like the journey, Robert. Ricardo vue 2.0, slash three. Great, great. Andrei, Laravel, PHP. Cool. Clement, thanks, thanks. Adam, Lucas. Well, a lot of stuff guys were using here. Oh, nice, nice. I see quite often views mentioned, which is good because we're on Vue conference. And yeah, I also see that it's a, version 2.0 is still oftenly used, which is completely understandable. It's a stable version, which was with us for almost four years. And yeah, like even being an expert on the third version, I still sometimes just would strap a new project and quickly do it on the version two because I just the kind of muscle memory and you don't need to think about any complex concepts, but yeah, we are mostly will be focusing on version three, which I think it's a, will be beneficial for most of you who are still using version two. Cool, cool, I see Carloi, Barthek. Yeah, thanks guys. Thanks for all the details. Really nice. C Sharp from position API, Dave, boss. Thanks, very nice. Cool, and also, so we're doing now the workshop which is part of the conference. And of course, the days when the conference main activities were held already passed, but yeah, I hope you liked it. I heard it was quite a lot of interesting announcements and talks by the core team members, so I'm really happy to present a workshop in this community. So let's move on, thanks for all the input. Actually, for those who mentioned React, I have a couple of slides comparing React hooks with Vue Composition API, so that might be a bit of help also to those. Oh, I see also Sergio mentioned the Vue School masterclass. Cool, yeah, I did some content for Vue School, specifically around version 3, yeah. Vue School is a nice learning source. Great to hear you're using it.

Okay, so a brief intro about Vue, because I think we will mostly know what it is, but just to recap. So, it's called Progressive JavaScript Framework. It started somewhere around 2015 by a guy named Ivan Yeo, who was formerly developing AngularJS at Google. And nowadays, it's a community-driven, super successful open-source project, which has, as we'll see, almost 200,000 stars on Github. It has certain design choices, such as template logic and data composition for the component logic, watchers, computed functions, which people who use Angular will find familiar. It relies on the common concept, which is called virtual DOM. The one that is also used widely by React, and it has a brilliant ecosystem of tools. We will look at some of them today, such as Vue CLI, to bootstrap a project, router, to basically switch pages and different parts of your viewport on the client side, state manager, which is a separate package called Vuex. We will also look into this today. It also has server-side rendering solutions like Nuxt. So if you've visited conference talks, you probably learn about them a lot. So we'll speak about some of them also. And it's used a lot across the industry. Not only by basically small teams, but also by enterprise level companies who need code reuse and functionality at scale. So, yeah, I think it's a great choice for any size of project. Yeah, just a quick recap about the current state of affairs. Yeah, I had this graph plot imported from npm compare. And here you can see several metrics such as amount of package downloads per day, I guess, or per week, for three major frameworks. So you can see Vue is steadily having a second place, which is maybe three times, four times less than React. However, in the star count, that's significantly more than for React. I think that's a great achievement for a project which is fully community, and Becca's founded. It doesn't have any big corporation behind it. So I think it's really exciting to use such a tool. I myself wrote several plugins. They are not that successful, but it was a nice experience, actually. I think that the way the documentation is aligned since version two and for version three, as well, it makes it really accessible and easy for everyone to build custom stuff on top of Vue. So if you haven't tried creating some reusable code, open source code for Vue, give it a shot. Maybe you will also like it.

Okay. Let me check. Okay. So yeah, a brief look on the field. What is the typical Vue component looks like? So it has, as I said, logic and the templates, you can output data from your model and you can bind to events and do certain, yeah, reuse some parts of the template, or reuse other components in the template. And the main part is in the JavaScript side where you can define your properties, your state variables using a data function or data object. And you can use methods to mutate these data, and you can have a bunch of other stuff like watch, computed, and other types of variables. So all this part basically is called options API.

3. Introduction to Composition API#

Short description:

Vue 2 is famous for its core API, where you define all the necessary properties and interact with them using the 'this' reference. The options API, still supported in Vue 3, will be deprecated in the future. In Vue 2, code and logic can be reused through slots, directives, plugins, and mixins. However, mixins will not be supported in Vue 3. Vue 3 introduced the composition API, which allows the use of hooks or behaviors. The release of Vue 3 brought significant improvements, such as modularity, built-in features like portals, multi-root templates, and improved TypeScript support. The composition API is the main topic of this workshop, and there is a migration build available for upgrading from Vue 2 to Vue 3.

That's what Vue 2 is famous for. It's in the core of its API, let's say you define all stuff that you need in the component in those properties on the object. And then you interact within this logic by using this reference that is basically helps accessing any part of the, any variable or any method within the component. So as we'll see further, yeah, as you probably all know, options API is something that is currently still supported in version three, but it's going to be deprecated in future and we're slowly getting rid of it.

So important note before we continue, we will try to focus on how to reuse certain pieces of code, certain functionality within, within view three real. And before we showcase how you can reuse code in view three, I just wanted to quickly outline the existing ways to reuse code and logic in version two, most of them are still available in, in between. So we have slots basically like, like in a web components, you leave certain frame or several frames in the, in the component markup, and then you can insert certain blocks into that. We have directives, which is again, very familiar to angular users. It's basically a custom attributes, which modify the behavior of a, of a tag. We have plugins, it's like a much wider applicable, a way to pack certain functionality. Plugins can have their own components, directives and stuff like this. So if you want to write something bigger than just a component or a directive, you probably need a plugin. So for example, Vue router, or Vuex are plugins in the end. And that's like the biggest chunk that you can use, the biggest concept you may want to use if you want to create a reusable pieces of code and pieces of functionality. We also have mixions in version two. Marked them as crossed out because in version three, this is something that going to be not supported anymore. So mixions were nice, with them you could basically add behavior to other components by adding a special mixions property. However, now we're not relying on mixions anymore in version three. So if you still have mixions in your V2 code, you'll have to rewrite them in some other format. Probably hooks or behaviors will be the best solution for that. So we'll look into this as well. So we'll have quite some options I would say, and yeah, in version three we will have composition API which gives us ability to use so-called hooks or behaviors. I will use those terms interchangeably, because yeah that's a terminology that is partly inherited from react-hooks. So yeah, that's how we will do it in our current workshop. Quick recap what we got in version three. So it was released, yeah almost one year ago actually. I think it was one of the view conferences where it was finally announced and it brought quite some improvements. I would say besides like complete rewrite which gave a more modularity to the code, it included several community built features like portals and other items it was brought into the core so it's now available without using any separate plugins. Yeah, also nice additions like multi-root templates when you don't need to wrap all the items into a root element so-called fragments. And TypeScript support became insanely better. If you've been using Vue with TypeScript, Vue 2 with TypeScript you probably know what I'm talking about because there are several nice solutions however you need to know your way around it to make a proper use of it. So now it is much more straightforward and easy. Most of my examples will be in JavaScript, however, but yeah, I have some links in the additional part where some TypeScript demos are showcased. And of course the domain big change is the composition API that will be the main topic for the day. Yeah, currently it's already version 3.2 and we also have migration build, a special tool that helps to migrate version two code base into version three. So for those who are using still version two and thinking about upgrading, there is a nice tutorial official documentation which explains how to do that. I will do a quick explanation about it. So yeah, we'll have time for this as well.

Okay, so now let's start with the actual content of the composition API. That will be, let's say, some theoretical part for maybe about another 20 minutes or so. And then we'll dive into the code examples, okay? So far, if there are any questions, or let's say, things you need to clarify, please feel free to use the chat. You can also use the Q&A thingy. But yeah, in the Q&A, we're sure that all the questions are stacked and visible to me. In the chat is more for ongoing suggestions or comments, or maybe if I at some point get stuck and you know what is the problem, please feel free, okay? Because it's quite common for those demos that after like an hour and a half something goes wrong and you can't see some bracket or something. So I count on you guys here. Good? So let's jump into the composition part. So what is the main idea about the composition API? The idea is that we create, we adding a special function on the root level of the object describing a component that function is called setup. And the function is a place where you can create or instantiate a reusable code pieces that will be reactively traced by the framework core. And that will allow, bind the logic that will be later can be used in the use, in the templates or in legacy blocks like methods or a watcher, for example. So we will see later that you can move all the version two way of handling logic into this setup function, and what is cool about this setup function is that you will never see this in it. This meaning the reference to an instance of a component. And that makes it very easy to extract it outside the component. But we'll see it better in the future slides. So for now, just remember that we have a setup function that has all the magic in it, and it needs to return all the stuff that gonna be used in other parts of the component, in the templates, especially out from it. If you don't return, then this will be not visible or available in the... Can you see the pointer now? Because I was using a separate app and probably now it's better. So, cool. So, two things to remember from this slide, setup function which accepts props as a first argument and don't forget to return stuff from the setup function because if you forget to return, you cannot use them anywhere. That's important thing to remember.

4. Exploring the Setup Function and Reactive Logic#

Short description:

In the setup function, we can construct logic for working with variables and objects. Built-in utilities handle this logic, but you can also create your own reactive functions and objects. Watchers and computed properties should only be used inside the setup function. The setup function is called once when the component is initialized and declares the component's logic. Variables and methods declared inside setup function are available throughout the component's lifecycle. Separate data structures are recommended for each feature of a component to facilitate reuse and maintain clarity. The ref and reactive utilities are used to create reactive variables and objects. Computed properties are similar to version 2 and allow for derived values. The .value syntax is used to handle the actual value of a reactive variable.

Okay, so speaking about the content of this setup function, what we can actually do there? We can do a lot of things, namely construct certain logic that will work with our variables, our objects. And we'll start here with built-in primitive, built-in utilities to handle that logic. But as we'll see later on, you can construct your own, you know, basically functions and objects that will be inherently reactive and will help you to apply your data model or your logic to this reactive approach.

So here we can see that all those items like watcher or a computed should be used inside of a setup function. If you use them outside, if you use them in a method or in a lifecycle hook, for example, it will not work, because it's only inside a setup function. Think of it as something like utilities that are visible only inside of a scope of a setup function, but even if you try to do it outside, you'll quickly see the warning. So it's an easy learning process, I would say.

I see a question from Rainey asking about the, what is a setup function? So setup function is, sorry, setup function is basically the place which where the component, component, it's a method that is called once, that's important to know only once, when component is initialized. And that method kind of declares all the internals, all the logic of this component. And along the way of our life cycle, of component lifecycle, variables and methods that are declared only inside setup function will stay available if you did not forget to return them. Like I mentioned here don't forget to return. That may be annoying sometimes when you have a lot of items, but that's the current way to do that. You have to return everything. So I think it will be more clear when we see more during the demo, the examples what you can actually do. So for now look at it as more like a theoretical introduction.

And I see a question in the Q&A. It says, is the script setup recommended way of using composition API? And that's great question. Let's get to this more in the summary, okay. But thanks for the question. Unfortunately, it's not visible who asked it but yeah, I see another question from TFO. Which one of these two ways to create reactive data is suggested? All state component in a single reactive data or create for each object a reactive data for primitives? I better try to share it somehow because it's quite a long one. I, let me share the screen. Let's put it like this. So that's the second question. I'll quickly try to look into this one. So which of the two ways, which way to create reactive data suggests all state component is single reactive data? Ah, you mean inside one component. So is one single reactive data or for each object reactive data for primitives? Okay. So this one is, yeah, can be easily answered now. I would recommend to have separate data structure for each feature your component has. Let's say if your component works with, I dunno, users and products, then you should create separate data structures for each of them and handle them separately. Why? Because in future, if you want to reuse some of this logic, you may extract it from there, right? It's the same as if you have, let's say, some module, JavaScript module, whatever, PHP, Python, it doesn't matter about the language. So, keeping the stuff separate can help later refactoring it. I would advocate for this approach. And even if you don't reuse it, or you don't extract it at the moment, it's still much more clear when the naming of the component of the, sorry, of the data structure is corresponding specifically to a certain business logic, okay? So, I would advocate for option two in your question, Tefla. Ah, you don't see the question. Okay. But can you see the, could you see the question now? If you can, oh. It's, okay, okay. It's weird. I'll just, ah, you see it in the Q&A, I'll just copy to double, to make sure. Okay. Like this, I think, yeah. Yeah, just some fiddling. Sorry for that. Okay, good. So yeah, I would advocate for approach number two. Good. So, what we can see here, just quickly recap the building blocks of a reactive logic. We can use ref and the reactive. Those are utilities that can help you to create a reactive item, sorry, reactive variable or a reactive object. Well, variable is for individual values. It can be like a Boolean or a number or string, something like this. A reactive is first of all, targeting the more complex shapes like whole objects, arrays, and things like this. And then you can do stuff with those reactive variables that are returned from those utils. For example, you can watch the value like here and if the value changes, then you can do certain logic. Or you can create, let's say a next level reactive items, derivative kind of that will be derived from the value of initially created object. So we have account item here, which defaults to zero. And then we have a plus one item here, which is every time the count is changed, it will recalculate the plus one and make it a value of account plus one, right? So when the count becomes two plus one becomes three, when the count becomes 29, it becomes 20, 30 and so on and so on, right? And it does not only have to deal with math or numbers. It can be any kind of transformation. So the idea about computed, it's very similar to version two, right? That you kind of checking the items that are mentioned in the callback. I mean, not, you are checking, but the things got view does this for us, right? You just write declaratively what you want to derive and view will be tracing all the dependencies and it will recalculate it for you, okay. That's a game. If you're using version two, you know about computed, right? So that's a very much similar to that. Again, this example is pretty simple. Just to give you an idea, we'll try to do more complex stuff in the demo session. What is interesting also here, you can see that there is again, no reference to this, to the component instance. What we create some state properties like those two guys, like count and state, but we're not saying these.count or these.state. That's not how you need to do that. So no this is used inside of a set of pumps, right? And secondly, what you may notice is that we, in some places we use like.value, and this.value is a tricky one that's actually needed for a proper handling of the actual value. I will show quickly this next slide, which I've specifically built with my Photoshop med skills to explain to you what's going on.

5. Reactivity and Accessing Values#

Short description:

When you create a ref or reactive object, it marks it and keeps tracing it for changes. The view is notified when the object changes, and you can perform actions based on the new value. The dot value syntax is used to access the actual value of a reactive object.

So when you have just plain objects or variables, view is not tracking them, right? It just doesn't care about them. Whenever you create a ref or reactive object, it will kind of mark it, and will keep tracing it, keep looking at it carefully until, if it's changed. And if it is changed somehow by user input or by timeout or whatever, then the view, like a framework reactivity system is notified about it. Under the hood, it uses so-called proxies, which kind of add extra wrapper on top of your objects that you want to be tracing. And then when this object changes, you get a notification that, okay, this object changed. If you wanna do something, please go, like this is the new value, okay? So that's the idea why this is important to let the view know that you are, wanna use certain value or an object as a reactive one. And then when you've done it, when you declared it in the set up function, then you golden, then it will do any kind of recalculations for you. But that's why that part comes with, sorry, where is my mouse pointer? So that's why this dot value comes in play. Like this is because the result of this creation of reactive object is an object, it's not a single simple value. That's why to get into it, to get the actual value, you have to call dot value. That's why it has to be like this.

6. Observable, Watch Effect, Ref vs Reactive#

Short description:

In Vue2, there is an item called observable that can track changes in an object or variable. The difference between Watch Effect and watch is that Watch Effect has a flush placed into a sync option. Ref is used for primitive data, while reactive is used for objects. You can also include computed properties inside the reactive object.

Okay, so that's actually not a new behavior compared to a View2. In View2 we have also item called observable, like a static method that can do similar things. So you can just call, you can call view.observable and then put some object or variable there. And then it will tell framework that please track the site and then notify me if something changes. So that was already kind of making its way into the API, but it was not mainstream in version two, okay?

Yeah, so I see a question for the, from Martin, and it was about the difference between Watch Effect and its difference from watch. Yes, we will look more closely into this one, but in short, this is the same as a normal watch, but with the flush placed into a sync option. So it means basically that when we are updating variables compared to the virtual DOOM redrawing cycle, that's about it. So your view activity system, invalidates the effects, those changes, and then asynchronously flushes them to avoid necessary duplicate callbacks. And so when you have multiple changes happening at the same, let's say, tick at the same update, and that's why there are different stages of this process. And you can manipulate on which state of this process you want to run this effect. Okay, so that's, let's say a bit in depth, but for many basic stuff, watch will be just fine, but for watch effect you have an extra option when you may want to do that, okay?

Fine, then yes, that's one more question about it was by Robert, about the ref versus reactive. That's a very, very popular question. Indeed, we have two ways to create items. However, for common use is that you use ref for primitive data, like I said, like numbers, symbols, booleans, strings and so on, and reactive, you can make use of it when you are dealing with the whole set of objects, okay? So reactive, we'll not be able to take a primitive value as an input. So you can put an object here, but you cannot put a primitive value here. And it's commonly used like this, that you will use refs for primitives and reactive for more advanced objects. In short, we will also see, I mean, again, more examples, but that's because also inside of reactive, the object that you're passing, you can not only declare single properties, you can also put, for example, computed properties inside of it and make it really more complex. That's why they are, that's, I would say the main difference. So let's then move on.

7. Lifecycle Hooks and Data Loading#

Short description:

The lifecycle hooks in Vue 3 can be used inside the setup function to run certain logic during the component's lifecycle. You can use the unmounted, unupdated, and unmounted callbacks available in the setup function. A typical example is loading data when the component is open, making API calls, and assigning the loaded data to a reactive object. This code can be reused outside of the component by creating a custom hook or behavior.

Yeah, I mean, yes, you can be able to do that, yes. Yes, true, true. Good point, we all inherited from an object in the end. So you can still put in that, yeah, sure. Good, let's move on.

So next part of the logic that can reside in the setup function is the lifecycle hooks. So we all know what is a component lifecycle, right? Components get created, rendered, then certain properties may or may not be updated and then a component may be unmounted, removed from the DOM. And during this lifecycle, we'll have a useful set of callbacks that we can employ to run certain logic like initiate some third party library or initiate some data loading or, yeah, track certain values, things like this, or maybe start a counter and all that stuff. And previously we used to have the lifecycle hooks on the top level of the component API for component options API. So you would use like a mounted, for example to call the logic that will be run when the component is mounted and things like this or destroyed when you want to, maybe before destroy, when you want to close some, I don't know, web socket connection or remove some event listeners and things like this. I mean event listeners which are outside of view control if you have any, for example, right? So those life cycle hooks still exist and they are available inside of the setup function. There's a unmounted, unupdated and unmounted callbacks that you can import from a framework, from view and then make use of them inside of a setup function, right? So that's a short example that showcases the typical solution when you want to load data when the component is open, co-calling some APIs and then when the data is loaded, you just assign it to your state variable. In this case, it's a reactive object and then you return from a setup function, the state object and the state object you can use to display stuff within your template, right? So that's a simplified example how you can deal with asynchronous data loading inside of a Vue 3 component. And of course, again, you see that there is nothing specific to this component that prevents us from reusing this code outside of this component, which is nice part about it that we can just put this all together into a custom so-called hook or a behavior. And this can be important in any other component where we need this data load.

8. Changes in Vue 3 and Script Setup#

Short description:

In Vue 3, the naming conventions for events have changed to start with 'on' and use kebab case. The first argument in the setup function is for properties, while other features like emitting events and accessing slots are available in the second argument, often referred to as the context. In the example, we see the commonly used options API components and how they are rewritten in Vue 3 using the composition API. State is stored in reactive objects, derived reactive variables are created using computed functions, methods are simply functions that need to be returned to be used in the template, and watchers can be set up to track changes. The script setup option in Vue 3 is a syntactic sugar for single file components that provides a more compressed syntax and better TypeScript support. Props can be defined in the setup function and accessed from the first argument. The return value from the setup function can be used in the template. The use of 'sync' on lifecycle hooks is not necessary in Vue 3.

Okay. And yeah, here I just have some items that were changed in version 3. The naming was changed. I think it's really cool that now the naming is more aligned. Just start with the on and then goes kebab case naming for each of the events. And this, I think, makes it quite more easy to remember and use when it has similar naming.

One more item. So we, I only briefly said that first argument is property. Properties is a common way in all the modern frameworks and also for a built in like web components, API's to propagate data from a parent component to a child component. So properties goes as a first argument and all other features that Vue provides for our components such as emitting an event, reading attributes, having access to slots, these all goes into a second argument, it's called context quite often. So if you need to emit an event you need to get the distract the second argument and get the event function out of it. So that's a bit of decomposition of what goes into the second argument. We will not deal much with it, but if you need to find some special stuff you can find it here in the context argument.

Okay, so let's look at this really simple example that kind of showcases an app that is just has one form and a bit of logic to increase the value of this form and a small method just to output the data that is for method. So here we see all the pieces of commonly used options API like state is stored in the data object initially, the formatted values are stored in the computed properties. You can say we could use filters for example for these. Filters is actually also gonna be deprecated in version three so that's something to be aware of. You will have life cycle hoops. We have methods to do this change of a value, just increment. And we have a watcher, it doesn't do much here but just for the sake of it. And here is an example how we actually rewrite the same code into version three. So what goes where right? That's just to compare them side by side because in a code demos I will not be using version two anymore. So just to quick recap, what are the building blocks and how they match on one another. So we, the state declaration goes into a rev or reactive, right? We put the default values here and we make use of the reactive objects that they return to us. The derived reactive variables like for formatting is created via computed functions. So computed function accepts a callback and the items that I mentioned in the callback are tracked. And for each of the change of those items that are in the callback, the new value will be calculated or computed, that's why it's called computed, right? The all-mounted hook I mentioned just before that slide about the life cycle hooks. So here you can see how it works. Then the methods. Methods don't need any special property declaration like here, it's just functions that do stuff, you know? And those functions you need to return them and then you will make... It will be possible for you to use this function in your template. And the last one is for the watcher, and here, again, it doesn't do much, just console logs the value, but this is how you can make use of a watcher, is put a dependency and then you get a previous value and the new value into the callback. That's again, very similar to AngularJS approach, so you probably recognize that pattern. Okay, so that's for the side-by-side comparison. Let's move on to more specific items. Andrey wrote, in a script setup option, you don't use return, is that true? So, just to quickly touch upon this, because there was also a question related to script setup. So, a script setup is something like you can write like this just if you have not used it, it's like this, which is just a kind of a syntactic sugar for single file components. And then you can use it together with a normal declaration and it adds basically a bit more, yeah. Yeah. How to say, compressed syntax, less noise of all those return export like export default and stuff. Right. And you can better use TypeScript for declaring properties and events. And in the end, it actually has a slight runtime performance. So that's a nice tooling to use. That nice way to use. And indeed in the script set up, you can skip the return because all the items are kind of in the global scope of this big setup function, right. So that's, yeah, nice syntactic sugar basically for those kinds of cases. Yeah, cool. I see some more questions were added. Let me see. So first item, if I'm not pronouncing it correctly. How would one define props in the new composition API? So in this example, there is no props defined because this is just a simplification. But normally you can put props as an argument for a setup function and you take the values from there. So they will be available for you because setup function runs before the component render but already when view has access to the properties value. Okay. So, and if you need to configure something in your component using props you can read it from the first argument. That's what I was showcasing just here. So the props are here and then you can make use of them, whatever you want. Okay. Cool. Yes. Correct. What you return from a step function you are able to use in the template. Yes. And one more question. Trying to use this feature like answer in life, but I always keep forgetting it, sorry. So, okay, I'm trying to do it now. I'm answering the question from Aaron. Do you not need the sync on the lifecycle hoops? Do you not need the sync? Yeah, you mean in that specific example? You're right.

QnA

Questions and Comparisons#

Short description:

Do you not need the sync on the lifecycle hooks? Yes, you're right. It was a simplification, but I missed the sync in that specific example. Regarding the WEF and Reactive, there is a nice article for comparison. If you have stuff defined by ref, you will have to use value to access it. The Composition API can be used as an alternative for Vuex. You can build your own objects that will be separate and store values outside of the component. The workshop is receiving in-depth questions, indicating that the community is approaching the stage of using Vue 3 as a default. The recording of the workshop will be available for ticket holders. You can extract logic into behaviors or hooks and import them into your components. The setup function allows for a more maintainable and modular approach. Vue 3 Composition API is similar to React Hooks, allowing for separate logic that is not bound to component pieces. The stateful logic, defined by ref or computed, is extracted outside of the component.

Do you not need the sync on the lifecycle hoops? Do you not need the sync? Yeah, you mean in that specific example? You're right. You're completely right here. It's my pitfall, it's indeed here. I have a sync, here I forgot about it. Yes, anyway it was quite a simplification. So I missed the sync here, of course. Otherwise it will not go. Right.

Okay, so one more. So this one I think I answered already. Give me a moment. This one for WEF and Reactive, again, there is a nice article for comparison. I'm pretty sure this can give a better explanation that I will do during this workshop. So please have a look at those. I pasted a couple of links into the answer. And one more question from Luka. Do you need to use value if you want to do a immutable change, meaning if you have a reactive array, you do not need to use full value, full value concat blah, blah, blah, or it's just mutable approach preferable? Okay. Do you need to use value from array? Well, if you have stuff that is defined by ref, then you will have to use value to access it, okay? That's for certain. If you want to change the value, you will also need to use the dot value. So my understanding, the first version should be correct, but let's check it when I have the IDE open. I'm pretty sure it is like this, the first the one you type, because you need to access the value. Okay, good.

Thanks for a lot of really, a lot of questions, really nice. I did this workshop I think somewhere, June on a, was it I think, Amsterdam Vue Conference or some other event? And it was much less people who already knew or experimented or used Vue 3, so there was much less questions. So I'm really happy that it's happening and the questions are quite in-depth. That means we as a community are approaching the stage when we use Vue 3 as a default, so that's great indeed. One more from Adriana, sorry. Answer live, I've heard Composition API can be used as an alternative for Vuex. Yes, that's actually also a nice addition. It's a kind of similar, well not exactly, it's like in React when the hooks were introduced, you could make use of a kind of similar structures like instead of Redux, it was called Use Reducer, like a special hook that could create you like a small Redux specifically for your component. That's kind of similar here, by using those reactive utils like I was showing now in this theory part, we can build our own objects that will be living somewhere outside of our component, they will be separate, you know, pluggable pieces that you can activate in the components where you need them. And indeed, they will store the value. So they will use, they can be used as a piece of books state. So yes, it's kind of true. And there's also I think some article quite well showcasing that, I may have difficulties finding it, but in short, yes. And I will show example of this, okay? Good. I'll try to remind about those questions when showing the code samples, but I may forget some of them. I have them in the answer tab. Sorry guys, sometimes Zoom UI is getting more and more complex, so there's more and more features there, cool. Andrei, one more question. Sorry, maybe we have recording. That's something the organizers should know. I suppose it is recorded. And yeah, it is recorded. And somehow, like they afterwards, it should be available somewhere in this, yeah, how do you call it? Logged in area for people who have a ticket. So yes, that should be almost 100% you'll be able to find. Cool. Just some last remarks. It's Karolin, and we'll get to the code sample, surely. So as a summary, again, you may extract the logic like here in your set up function, and then make it more not just a big pile of code, like a super function, you know, like the one that takes like three screens to read and does everything and this hard to maintain. You can actually extract stuff into so-called behaviors or hooks, and then import them piece by piece. So here, it's an example, for example, we have some components and you have hooks or composables. And then where you need certain piece, you can just import it and make use of it. So imagine you just basically make everything what is written here in the setup function. Just one hook and then you can import this hook like this in your component and then it's just one liner that gives you all the variables, all the methods that you may wanna use and stuff like this. So that's short let's say pattern. Yeah, concerning the recording, yeah, I suppose somewhere between tomorrow and the week. That's for sure. Cool, so just a quick comparison against React Hooks because React Hooks is quite a popular tool as we all know and then maybe people who are switching from React or doing also React, so maybe helpful to quickly outline the differences. So we're not using the magic this in the component code, like React Hooks gave an opportunity not to have this state, sorry, a class properties and plus methods with these. So it's the same kind of thing. You're not bounding the logic to the component pieces. It's just separate logic that leaves in the setup function. Then we have, it's in parallel with all the API. So it's also same with React when you can still use class components and functional components with hooks, you can still combine them as you like. So that works in parallel as well. We extract the stateful logic. That's what I was trying to show earlier, that stuff that contains certain values like those that are defined by a ref and maybe those that defined by a computed. This is called a stateful logic in this case, right? The logic that has values that it needs to store and needs to reuse in the next iterations, right? So it has state basically. And this stateful logic is going outside the component.

Using Composition API with Core Libraries#

Short description:

The setup function in Vue is only called once during component initialization, unlike React hooks which can be re-run. This eliminates limitations such as not being able to use hooks inside loops or if-else statements. In Vue, you can use reactive objects to store nested objects and computed properties. Two Refs can be used to unwrap the contents of an object and provide each property as a separate reactive variable. The Vue Composition API can be used with core libraries like Vuex and Vue Router, allowing you to read and write values, call actions and mutations, and track dependencies. The library VueUse provides a collection of hooks and small behaviors for various utilities, making it easy to enhance your Vue components with reusable logic.

I probably said it already a couple of times, but I cannot stress this point. That's a pattern that helps to reuse logic more nicely. Let's say, okay. And yeah, the quite common naming convention to have a use prefix that's also used quite a lot in Vue world. Okay? Just the outside of this kind of what is not similar to React hooks is that set up function in all is only called once. As I mentioned earlier, when the component is initialized, right? It's not like re-running the whole component as a function like it does in React Space. It just runs it once to declare stop. And thanks to that, there are no things like limitations. If you worked with React hooks, there are those things like you cannot put React hooks inside of loops, or if else statements, then it kind of breaks. But here it's all fine because it's just run in initialized once, okay? So, yeah. That's in short. No more React. Just one last slide. Here, we are comparing a simple component that does increment the value and calculates the doubled value of this item. On the left, we have a React version and on the right, we have a Vue version. You can see that kind of some parts are similar, meaning that all the logic, again, does not contain any connection to this, the instance of a component and it uses kind of utilities that are imported from the library, which kind of remind the way it's done from Vue. That's actually all the example. It uses the composition API instead of the modern Vue 3 version. So, this is for version two users. If you're not using version three, in version three you can just import it directly from Vue core. Anyway, so you import those utilities, you create a state, and with those utilities you do certain modifications, and then you show stuff in the template. So, actually here is an example of a reactive object that I mentioned earlier that you can put not only just as let's say, primitive values, but you can also put nested objects, or you can put like a computed properties inside of a reactive object. That would not work with the Ref, okay? So that's a reactive is more advanced in this in terms of tracking. Yeah, good catch, Andrei. So two Refs is basically unwrapping the contents of the object, okay? So it kind of opens an object and gives each of its properties as a separate reactive variable, okay? So here we have a State, which is inside count and the double. And when we use two Refs, we will get count and a double separately, okay? So that's a quick shortcut for this kind of operations. Because otherwise you could do it by hand, right? But it will be again, more lines in the return statement. So we have two Refs utility for this. Okay, so that's a quick example. Now let's look at using Composition API patterns in the Core Libraries. By Core Libraries, I mean VUEX, first of all, a router and couple of more. So again, we will see more of these in the code examples. I'm just more, again, a quick theoretical overlook how this works. So both VUE router and VUEX, they come in a newer version. So if you're using version three of VUE, you have to use version four of VUE router and VUEX. That's like a set in the peer dependency. So if you're installing version three of VUE and then you're installing a router, it will automatically put the right version. The same with VUEX, but make sure you're not trying to install the old version because old version does not have hooks, those custom hooks important, so it will not work. But in a modern, the latest major versions, you can import special hook. Again, look at the way the syntax is written, it's a use and then the store, so use something. And in the setup function, again, you can get a store from it and do similar things like you'd usually do with store, like read the value or write a value, call actions and mutations, that's both possible, so that's a quick pattern, how that is done in the version 3, okay? Hope that gives some idea. We bound values from a state into the compute function and what happens that Vue Core tracks these dependency inside of your store and whatever it changes, the computer function will rerun and give you the new value of a store, so that's how you read it. And if you want to commit, then you just this store object that you get from the hook has options to commit and to dispatch so basically to do both actions and mutations with the data you need. So that's in short how you do it with Vuex. Clement, I see your note. Honestly I have not tried. Let me copy this and we will give it a shot, okay? I don't know, I mean, maybe I tried that but I don't have a answer right now, we can have a look. I copied your comment, we'll try it later. Yeah, yeah, I like to check. My take is that it should not because ref is not tracking its dependencies. So computed is specifically like in version two, computed is a function where a viewPoer identifies all the, let's say, mentioned variables and then tracks their changes. So I think here it should not work, but we will try it. Good, and one more for the router, the same thing, you can import special hooks from a modern version of router. And those hooks gives you the same behavior like you were using with a good old, this dollar router, right? You can get your current route. You can get the parameters. You can do programmatic navigation, things like this. You just can make use of those objects that are returned from hooks. And again, they are fully, let's say, composable with other building blocks that we just outlined in the introductory phase. For example, you can be tracking the parameters of a route, and then if it changes, you can rerun some logic to get a new data, right? So that's kind of how those pieces play together. And again, we will see that more in the examples, okay? So, yeah, that's Willa Martin. I saw your message caveats. Yeah, I think it's more important that we now dive into the examples, and then I will showcase them there, yes. I guess it's, I think it's quite some stuff to go through there. And one more item that I really like as a developer, as a user, is a library called ViewUse. It's basically a collection of all kinds of hooks, all kinds of small behaviors, and that can give you access to all kinds of utilities, not only timeouts and like throttles, but also stuff like related to browser API, stuff related to like a DOM API, tracking position of a mouse or tracking like a field that is focused, like all kinds of stuff. So, I think it has like a hundred different hooks that are really like small pieces that can be inserted into the component and make it like those pieces of logic that you may need once or twice in your app, but then you don't write it yourself or go to search on the stack overflow, you just take it from the library okay? Yes, yes, I completely agree. Actually, there were I think three or four libraries that tried this approach, like in React ecosystem there was also certain collections of those hooks, those pieces that you can just install as an NPM module and then use, but I think Vue.use now is the one that kind of dominates and has the most often updates and the top rating in the star, so yeah, it's currently the one to pick up. Yeah, I actually have also a demo with it I will show you. Cool, so there's one more question from Tefo about the Vuex, I guess, me asking, no more map getters in this version, so there is a map getters, it still exists, but you may not need it anymore. Let me, so there, you can still be able to do that.

Q&A: Vuex and Composables#

Short description:

You can still have a map actions and map like mutations. The map mutations and map getters still exist. There are some nice libraries to recommend. Vuex is still a good choice for complex applications. You can use Vuex accessors in hooks. Let's move to the demo. Pina is a small state management library. It's great that there are lightweight approaches being experimented with. Vite is a nice tooling showcased during this event. Composables are still quite new in Vue. The feeling in Vue is that there's enough time past. Hooks are not a magic bullet in React. Class-based logic is still more readable.

I'm just trying to open the specific part. You can still have a map actions and map like mutations, I think. Yes, it still exists but you, yeah, you don't need it always, okay? You may be fine with just that, okay? Because I can imagine if you have too many items to read, then why not to make use of those things, okay? Here, just a link to the docs. So the map mutations and map getters and stuff do still exist.

Okay, some nice libraries to recommend. And what does it do? Is it kind of like a reselect for React? You can find some specific data in your Vuex. Is that data or let's judging by name what, If we have time, we'll explore what the DSL, okay. The main, cool, cool. But it's cool that you guys have some open source stuff to share. I think that's always welcome in events like this. Yeah. If it's not too much, but thanks for sharing data anyway. Cool.

One more question from Ricardo. So questions by Ricardo, what would you choose, what would you choose the old Vuex way or the new composable approach to manage state between the components? Yeah, it's kind of too many too little input data because you put, hard to say like generic answer. My take on this is that Vuex is a steel way to go for complex applications because Vuex is a, let's say well-known standard how to structure the logic. And it's easily used for let's say when you test your components, right? You can just put a mocked a piece of state and verify the components behaves properly, right? With hooks, you will not get that. So, of course you can still test hooks and make sure that the behavior is similar but with Vuex is just all the infrastructure is there. So, I would say if your app is big enough, I would rely on Vuex but it's just the fact that you can make use of Vuex also together with components. We will see that just in a bit. So, you can actually take this Vuex logic, sorry Vuex accessors into your hooks. It still works, okay? That's maybe a bit of unexpected but it still works. So, you can access certain pieces of your state in your hook and then only return that piece. So, they are not one or the other. They are kind of made, this approach makes it more like less connected to each other. So, you can choose either or both I would say. Okay. Finally, so let's move to the demo. Just a quick shout out. I have this link to these slides, these slides you can get just almost now. I will put quickly a copy into the chat. So, here's the slides. It's a PDF, and the demo, the code snippets I was using, I will be using, sorry, is in this repository. It basically has two parts in it. It has a samples, oh, let's open, so that it has basically two parts. It has the samples. I can click it. I just sub-tree. Okay, I, because I created a separate report in this folder, now it's just referencing to a separate project. I will quickly commit it so that the samples is actually the pieces that I will be reusing to show within the demo because demo is just a purely created view project that I will be kind of building or adding from scratch. Okay. Let me then open the, so I will continue now with the demo, but make sure I will make sure that the samples folder is also filled with content. Okay. Just was finalizing it today. Some things, I forgot. Cool. Another item by, Andre. I hope I pronounce your name, Andre. Right. I have found Pina very easy, smaller with the Beauty tools, and the three can mean managed state without for example. Yeah, Pina indeed. It's one of those items that were showcased also, I think during this event. And it's kind of a nice small state management library kind of thing, right. And I think there's also a nice article showcasing this in the View School, if I'm not mistaken. Was it here? Pretty sure it was here, but. Yeah, I think there's a nice article about it that I read. Yeah, pretty cool. But again, it depends, like what are we building for? I would give it a try if it was my, let's say, a project I'm just starting and it's not something commercial I'm already committed to doing and supporting for next quarters, right? Which will have more many contributors and like really deadlines. So it's not about Pinio specifically, it's about all, let's say a new software that is popping up. I'm pretty sure that they will do a great job and it will work, but just I would not commit on using these for something that has deliveried deadline. But anyway, I mean, it's great that guys are experimenting with a lightweight approaches. The same goes, for example, for Vite, right? The really nice tooling also showcased during this event. And yeah, it's pretty, pretty amazing how we can make improvements in the dev setup and not wait for like dozens of seconds and have the transpiled output directly in your browser. So I'm really looking forward to these becoming like a standardized way to have the developer set up instead of a Webpack based stuff, cool. Yeah, before we go into the next part of the demo, I just wanted to clear all the Q and A parts. So I have a question by Dave, saying, I heard some React developers are finding after using hooks for a couple of years now that they are not magic bullet, they thought it would be. As composables are still quite new in view, what is the feeling in view in the, there's enough time past? Well, first of all, I'm not like a pro daily React user. Yeah, I do have project that use React and I kind of know my way through it. But I would not consider like myself, a person who can really compare all the, you know, ins and outs and the pros and cons of using hooks in React. So yeah, for me, yeah, the class-based logic is still much more readable.

Adoption and Evolution of Composition API#

Short description:

The adoption rate of the composition API in Vue 3 is growing, especially in larger projects. However, there are still some downsides and pitfalls that may arise from using certain patterns enforced by the framework. It is similar to the evolution of JavaScript syntax and code organization, where improvements were made on top of already functional syntax. Overall, the adoption and improvement of the composition API in Vue 3 is expected to continue.

However, for typical cases, I just remember how it should be done. But if I would be writing something complex, I will probably have some hard times with hooks. In terms of view, indeed, it was, let's say, two years late or maybe, yeah, like a year and a half later, introduced in View, kind of similar concept. Like I tried to show in this comparison, this approach with reusable, functional pieces that are functional utilities that make use of reactive code patterns. But here I think the adoption rate is still not, like, that big. And again, judging by this workshop that I was doing, I think since beginning of the year, the adoption is growing. Definitely just by this introductory part in the chat that we had in the beginning, there's much more often you can see version two mentioned. Oh, sorry, version three mentioned, much, much more often, but it's still not like more than a half I would say. And also the bigger the project is, usually that's where the complexity resides and where the tough cases, corner cases may reside. And that's where you may see downsides of using certain patterns that the framework enforces. So yeah, I think the time is not there yet to see those pitfalls, but definitely that there will be some improvements or maybe like with any other approach, like community usually evolves to find some usable solutions on top of the things that don't work fully. You know, guys, come on like what six, seven years ago we didn't have classes, right? Like it was fine, people could leave without it, we were having all those kind of constructions, a bit custom in each project and people kept writing the code, right? Now we have quite modern and comprehensible syntax in the language, so we're now only talking about the specific pieces somewhere on the, let's say on the libraries level. But yeah, look at how far we are from what it was before ES6, right? It's improvements on top of already quite well working syntax and code outs. So, it should be fine, I think.

Coding with Vue CLI and the Composition API#

Short description:

I have a fresh Vue CLI generated project with version three of Vue. We will start with a simple counter component to demonstrate how to use the store in a modern Vue 3 project. The Vue initialization API has changed in version three, using the create app syntax. This allows for better separation of functionality in different instances of Vue. The create syntax is also used in other tools within the Vue 3 ecosystem, providing a unified naming convention. We create an app instance connected to a store and router, and mount it to the app element. We start with a simple counter using mutations and actions. The counter is currently synchronous, but we can make it asynchronous later.

Okay, by the way, I think there's no more Q and A part, but really, really fascinated by amount of questions. Happy about them, I hope I could answer them with some useful content, at least maybe some links or some mentioned items, you can further Google about it and make your view about certain aspects. But let's move to the coding part.

What do we got here, this is different. And we have, so this is... Okay. So let me know if the font size is good enough, if it's readable or not. If it's too small, put something. Okay, cool, thanks, Relly. Um, just one more question from Bess. Might be useful for some for our view project, Apollo client cache, GraphQL has completely. Yeah, a good point, Best, by the way, because that's something quite often, also happens for also react the ecosystem. As far as I know that Apollo client brings all kinds of parts to not only just query data, but also to cache the data and to add certain how they call it, like a client level pieces of data so that are just derived from existing data and things like this and reusable. Those components that do the query and all that. And it's kind of takes over a big part of data management that centralized data management in the view applications, the same as for React. Yeah, I heard about it as well, yes. So you may want to think what in the end you wanna use for your... Only if you're using GraphQL, that's the point. Because Apollo Client is specifically, I'm talking about the GraphQL here. Cool.

Yeah, so here I have just a fresh Vue CLI generated project that just has currently version three of Vue. And as I mentioned, it's one major version up the VueX and the router versions that we will use in it. It has all that stuff, it's pretty standard. And I also already installed a VueUserCore to showcase some of the items. What I also did, I put just some Bootstrap CSS to make it look a bit nicer. And I have a footer here just to demonstrate some of the features. And not any more modifications were done. Okay, so let's see what have we got. I think I can just start with, just starting the project, simple as that. Just two quick heads up. Does everybody feel comfortable with using Vue-CLI? Because I think that's the, let's say, basement for productive Vue development. It's also part of this core tools that are forming the ecosystem and I think knowing how to use it. And it's important to really save you a lot of time in the configuration. So if there will be any, let's say, who never used it, if you have some more comments about it, I can quickly show, but I hope you already know how to use it. Cool. No special mentioning, that is good. So I have, I have sysdemo application, which I only replaced all this links with some text to have it look a bit more custom and really that I have prepared something. So let's start with some of the examples, let me quickly check this. Oh yeah, it's here. So let's just restart with a simple example like usually happens that we write some stateful logic, some item that will store the data in the Vuex. Maybe first in the component and then Vuex and then move on to more complex stuff. So I will just start with a component that will be using a counter. Of course let's start with the simplest example but it will just show the idea what parts needs to be implemented to use the store in a modern Vue library, okay. Modern Vue 3 project. But don't think we will be only talking about the counter, it's just to add some code. All right. So, before we start adding the code, some additional items. How the Vue initialization API changed in version three. Like previously we used to have the code NuVue version, right? And then you put element and then render function and stuff like this. That's how it was done in version two. Here you can see that it's already using version three syntax, and it uses this create app syntax. And I think it's really nice, and not only because it has a certain improvements in terms of separating the different concepts of different different instances of Vue. Because previously, with this syntax, that was not possible to separate functionality that you are using. That you are adding two different instances of Vue because it was if you're adding a custom component or a plugin, then it was added to all the instances in scope. However, with this new logic, each applications will be having its own its own list of items, its own list of things that are that are added to it. So you can have one up here, second app here. And for example, if the second app in this one mouse, let's say, to app, app one and this app mouse to app two. And if this second application does not need a router, then it will do it like this, and then the resulting bundles will be, will not contain router in both of them. So this syntax was not allowing this, but that's nice improvement. There's actually an article that explains it in more details on the Vue School website, so you can have a look on to more explanation. But however, this create syntax, so starting with the word create, and then do something is common also for other tools within Vue, Vue 3 ecosystem. So if you look at the initializing the store, it also uses create store instead of new store. And for the router, it does the same like create router, this common pattern I think also nice kind of unification of how certain things are called. And it's maybe also something that you may think if you're writing your own custom parts, maybe plugins or something, you may also make use of the same naming conventions, right, to create initialization function with the similar naming, right, just so that everybody understands, okay, this is the entry point, right. Okay, anyway, so here we are creating an app instance that is, we're connecting it to a store in the router and mounting it to the app element. In the store, we have nothing right now, so let's start with a simple again, count, just it's very, very common. But again, bear with me, we will do some more fun later, okay. So we will have a mutation that will basically increase the counter, right? And let's start with also, action, okay. How it will be here implemented, that we, actions as we know serve the purpose when we need asynchronous logic. And in this case, we can just pass the commit in the first argument, and then we can call commit certain mutation, right? So, for now, this counter is totally synchronous, it doesn't have to do much, but we can later make it asynchronous.

Using the Store and Extracting Logic#

Short description:

To make use of actual counter values in the component, create a new file and import computed and use store in the setup function. Use the store hook to access the store and retrieve values from the counter. Return the values you want to use in your DOM elements. Put the component in the desired location, such as the home page. You can also use actions by calling dispatch directly from the store object. Extract the logic from the setup function into a separate file, such as a hook. Use the hook to access the counter and retrieve values. You can customize which values to use in your components, depending on your requirements.

So this is the very simple state. Now, if we want to make use of actual counter values in the component, we will create a new file. Also, don't forget to use extensions for your ID of choice, because that also makes your life easier and faster. I'm using vetour, there is more nice tools, but this one, I think, is kind of the most popular at the moment. So it will create a default pieces for me. So, I will already important stuff. So I'm not wasting your time. I will import computed and use store so that we can use it in the setup function. And in this setup function, we will first make use of the store using this store hook. And then, as I mentioned earlier, we can use items we get from the counter to read the values and increment the values. And what is important that I mentioned is to return the things that you want to use in your DOM elements. So I will just copy those here. Yeah, I see that there was some raised hand, I will get to that just in a bit. Just some example here, some markup here, so I have a button and the value here should work. Let me see. And of course, we need to put this object, this component somewhere. So let's start with just putting it into the home page. That probably should do the trick. I'll just comment out the Hello world example. Here, we have the counter and by pressing a button, we do increment the value, right? So, as simple as that. We can also see that it's happening in our dev tools. Also, about the dev tools, make sure you have different dev tool. I mean, now it supports version three but there was a time when it was not supporting both versions and it used to be two different major versions of a browser API or also a browser extension. And if you're using the older version of a browser extension, it may not pick up the new version. So, you may just want to install another one. So, if I look at my extensions list in Chrome, you will see that it will have two versions because of that, but maybe now it's already support both. I need to find where is this raised hand. Not on purpose. Okay, cool. Fine. Yeah. So, let's use mostly the chat for signaling. Okay. Let's very simple example, just to extend on this a bit. We can also, since we have a counter that we have a mutation and we have action. So, from the component here we're using a mutation but if we want to use mutation. We can, sorry, if we want to use action, we can still do that. By, again, from the store element, from the store object, I can call dispatch directly and it will give me the item that I need on counter increment. And then I will be able to do this using action. So, here I am calling already an action. So, in your components, just by using store object that is returned from new store, you can access both of ways to mutate your state. What is the next step with it? We can, of course, put it somewhere, let's say, outside and make use of a hook that will be able to bring us the counter. And this is, again, like I mentioned, all this stuff, all this logic that is happening in the setup function, should stay here. It should go to a separate file. And that is what we're going to do now. We will start with a counter example, and then we'll build more models, more data into the application. So, I will create a hooks folder. And I will create a user counter example. And I will basically just copy the whole thing, it's just easier. Like, since I still have only this in my setup function, it's easier. I'll just... And I will name it UseCounter, again by convention. Okay, what I'm missing, of course, is those guys. They have to be here, right? Otherwise, I don't have a computer or store. So these, now I can just replace that whole thing with importing my newly created hook. I will use this auto completion, because with asterisk it doesn't work, and I keep forgetting the name. Normally you should use asterisk, of course. The use counter and they will go. So, that's how we extracted all that stuff, including usage of VUEX, into that component, into that hook. And now we can have the same functionality still working. Right? Let's see if nothing breaks or something breaks. UseCounter is not defined, because I did not watch. UseCounter. UseCounter is not defined. Okay, so the functionality still works the same way. What is nice about it is that we can... we may not need all the items from here, we're only using Increment With Action, so we can only take those two and only use those two, right? And it will... we're still fine, right? Or if we have another component where we want to use only the value, right? We just consuming the value from the store, not incrementing it. We again can do that pretty easily. For example, if I take it here, let's say...

Using the Counter Value and Working with Props#

Short description:

And I will just use the value, not any other parts of it, okay? Probably this, so now we have access to the counter here and we only imported the counter value because we don't need the rest, right? This newly added feature, let's say it's a new feature, we can just add it to the exported values and when we need it somewhere, we can just ask for it in this deconstruction and then make use of it in the template. The counter value is read only. The component showcases a product in the catalog, with a custom price property and an emit function. Reading props can be done in different ways, such as from the first argument or using a more modern approach. The parent component demonstrates passing data to child components, similar to Vue 2. The child component and list component are also briefly mentioned.

And I will just use the value, not any other parts of it, okay? Probably this, so now we have access to the counter here and we only imported the counter value because we don't need the rest, right? So it will be like this and then it will still work both here and both here, right? And of course, if we keep extending the contents of this hook, like it was in my slides, like we want to have, let's say, some computed function that does some modifications of this value, then we can still do that. This newly added feature, let's say it's a new feature, we can just add it to the exported values and when we need it somewhere, we can just ask for it in this deconstruction and then make use of it in the template. So that's probably because the initial value was like a string or something. That was not a string, so Y gives me none. Probably counter. That's the trap I was talking about. But the problem is that this object is something I need to refer by a value, and then it will, I will be able to get the actual value of it, right? So here we have a counter with some extra features, and we created a separate hook from it, and this hook will be reusable in other components just like this, okay? So that's just for the start. Now let's add another feature that is working with events, so how you can, yeah, make use of emit in the viewtree version. For that, I will need to create some more components. But before I go into this, I will quickly answer the questions. So Adriano was asking, are you using white? No, I'm not using white. And one more thing, speaking about the white, there is also a nice repo which actually uses white, and it showcases a lot of new features. That demo is, like, way better than I will be able to create during this workshop. This one, please have a look, give it a star, and that this guy's really amazing that he created it. It's called Vue 3 Playground, and it contains, like, each of the... almost each of the features that Vue 3 has. That you can just open the piece of code, run it, like break it, you know, adjust it, and learn it by doing, so that's amazing repo. And this one uses actually white. Okay, so the second question by Adriano, can you modify counter value in the component where it is imported? Okay. So meaning here, right? Like if I only import the actual value, that's the question. So yeah, we can just see what will happen, right? We will create a function that will be changing the value, and you'll see that it's how it is reacting. Okay. Create function. We import here and then we clear the button. Here we have this change button. Uh, so you see, uh, maybe I forgot something. Change. Change. Change. So it does not do anything here because the, uh, if we try to do it like this, it will just give you this, uh, that's what I wanted to show. It says that the counter value is read only. So we, uh, what we're getting from here is already, uh, something that you can change directly. Yeah. Um, okay. Uh, moving on. So that's for the. For the simplified, uh, counter example. Uh, let's, uh, create some more, um, stuff and, uh, experiment with it. Um, so I will use this, uh, demo, which is, um, like a component that is kind of showcasing, uh, like a product in the, in the catalog. So I'll create it here. Uh, this component is pretty straightforward. Uh, name, and it has a property of a price so you can configure your product by giving it a custom price. It emits an event. It's just the name of the event. It can be anything instead of signal. And it uses the view tree composition, and here you can see how we use the emit function, right? So we, uh, use the props. I remember there was a question about the props. Right. How do you use the prop? So here's the example, right? Reading the props from the first argument, uh, it can be also done, uh, a bit more modern way, like something like this, uh, price. Uh, and then, uh, you just take it, uh, from there and then you use it. In India, in, for example, in this situation, or you can use it, uh, somewhere else in the cold, uh, in order to, to, to, to make it more using the simple properties mechanism. Uh, to, to, to pass the data from a parent. So I will now need to quickly recreate the parent also to, uh, explain. Um, so, uh, this uh, here I'm using the syntex of a defined component. I can see that. Yes. look at these. This is on purpose so that I, um, That's it. Uh, you can, you, it doesn't do more than just the normal export default without this wrapper, but it's more beneficial in terms of, um, uh, the TypeScript, uh, and the ID tooling support. So, uh, that's, that's okay. So I will do one last thing. So that I can, I can quickly make, uh, um, a image, uh, that I can then maybe, uh, useful to do that. Um, so this is a child component and that will also create, uh, uh, um, list, uh, component here. Um, for that, I will quickly replicate my, um, screens. Okay. I'll quickly create one more screen here. Um, and so what do I have? I have a parent component that is just has like a catalog title and it places two child elements. I mean it can be more, can be a less elements and it just shows the way that we can pass properties. It's pretty similar to how we did it in view two. Of course, we can also make them more dynamic right by adding, like a data property somewhere here.

Using Multiple V-models and Emitting Events#

Short description:

We can pass properties using the dynamic property value syntax. A new page with three product items has been created. The sum of values is displayed, and when the 'Add to Cart' button is pressed, an event is logged in the parent component. The setup function allows for the replacement of a method object with functions. In Vue 3, multiple V-models can be used to bind to different properties. The childAdvanced component demonstrates this functionality by having separate price and quantity properties. The emit variable is used in the child component to emit events to the parent. The 'emits' property is used to declare the events emitted by the component.

We can also, of course, pass the properties using the dynamic property value syntax, right? So I created this page. Now I will quickly add this to the router. And the last step is to add the link to it. Actually, for adding more links, I have, let me do it here. That's too much. So what, do we, what I forgot, I forgot the price. Price has already been declared. Probably here. Oh yeah. Okay. That's because, yeah, we're importing the same name. So it will be like price internal, for example. And then it will, you see it here. But if we don't want to change the naming in the template, we can just use like assignment like this. And then you can keep the original name in the template. This should not be a problem. Hope now the problem is gone. So what have we got here? A new page, which has three product items. It's not looking very fancy, but you get the idea. We have the sum of values. And then when we are adding to a press add to a card button, we get the event. And this event is also locked in our parent component by virtue of just a simple lock function. That's how you can also like you can replace a method object with the functions that reside in your setup function. However, if you let's say in a stage of migrating of something big, you can still have a methods object. That's not like mutually exclusive yet. So I can have a methods and put here, let's say almost the same thing, right? Log, and I can still do it right here. The only problem, of course, it will override the existing log function. But just for the sake of demonstrating the compatibility, it will still work. So I can log the values the same way, while I'm using the old school methods, right? But that's just just to show. Go back to this one, again. Why I'm going back to this one? Because I can extract it and make use of it in a more nice way, right? So, here I'm passing the, like, in Vue 2, the value, and it's all fine. What I wanted to showcase that currently we have a relatively simple component that has only a price parameter, right? But normally you would probably have multiple fields that you need to configure. And we can do it in many ways, right? We can pass, like, define a price. Instead of price object, we can have, like, some property called, let's say, config, and that will be, like, some object that will have all the stuff in it. That's fine. That works if you don't change each of the values separately. But if the values are changing, maybe changed separately, then the nice new feature of version 3 is so-called multiple V models. So we can now, when we have a component with a property, we can also set the V model value to it and change it from the parent, right? I think that's a known approach. So you can do, like, V model-price, and then assign some value to it. Let's say... And then, along with changing this one, your model will be changing, right? We'll put, for now, let's say 100. And then, just to show that it's changing, put it here. And then, if I'm changing it there... Oh, that's where... One second. Why is it changing this? Because it was re-rendering here, of course. That's what I wanted to show. Like, if... Other way around, of course. If I put the value here, then this value will be propagated into the component, right? And if I change this value in the parent, it will also be propagated in the component. Before version 2, there was only one V-model possible. However, in version 3, you can have multiple V-models on one component to bind to different properties. And for that, I will create a separate component that will have this implemented. This time, I'm just copy pasting more stuff so we do not do the same typing. And it looks a bit nicer. We'll close the rest. And here, I will use the childAdvanced. And for this childAdvanced, I'm able to set up multiple models like this. So childAdvanced has more properties. It has a price and a quantity, like two numeric variables that may be changing separately. And now I can configure them, bind them to specific values in my parent scope by using two v-models that are pointing to the specific items, okay? It's not directly, let's say, composition API part, but something that view three adds. So this last product here, it has, let me just separate it a bit. So this last product, it has two values in it. And those values are set from the parent and you can track those changes. So that's for the emit, how you do the emitting in the child by using the emit variable from the context. And also important item, you have to declare what events does your component emit? Like, you see here, I have this property emits. Like, if I will create another event saying, not here, but let's see, I create an event here saying like this, then I should get a warning because that's, wait, it's, I think there used to be a warning. Now, I'm not sure, anything, I'm pretty sure there was some explanation that was used to have a warning in this case, but then it's checking what items you are declaring in the meet. Strange, maybe because of this. Okay.

Q&A: Data Loading and Search#

Short description:

I will answer the questions regarding replacing the data block with Reactive, the use of define component, and the support for class style syntax in Vue. Then, I will proceed to the data loading part of the demo, where I will showcase the setup for loading data with Vue 3 Composition API. I will create a repository folder for API calls using JSON placeholder demo backend. Next, I will create a data load component that will load the data using a card template. The component will contain a reactive element to track the loading status and allow for extraction to separate components. I will start with a simple version using ref to store the loaded data and a function to load the data asynchronously. The lifecycle hook will be used to run the data query when the component is rendered. The user data will be returned and displayed in the template. I will also add a search bar to demonstrate searching within the list of users.

Okay. Nevermind. But don't avoid declaring all the events that you have in your child components. That's specific property you have now in your declaration. Maybe it's checking during the build time or something. I'm definitely sure it does have some checks.

Okay. That's that. I also saw a couple of questions and yeah, before I go to the next part of the demo, which is about data loading, I will answer the question. So please either put them into the Q&A or put them in the chat. Or you guys all went to check this GitHub link. And it's really worth it. The kind of replicates a lot of similar stuff that I'm talking about during this workshop. So the questions. Starting by question by Martin, could the data block be replaced by Reactive? Could the data block be replaced by Reactive? So I assume you mean this block. Yes, it can be replaced. Yes, true. The only thing I mean, if you. Yeah, yeah, absolutely it can be replaced. So we can just move all that stuff there. Like this, and then we just remember this, that unref function that was on one of the slides so we can also make use of it here, right? And then we will have the same values here and here. So yeah, that's a totally valid change, yes. Other one, question by Steve. Why does it need defined component here but it didn't in the counter example? Yeah, that's as I mentioned. I just had different ways to define components just to showcase that there are different solutions. Only for that you can you can live without a define component or you can use define component in every case. That's it can be used interchangeably. Just the fact that define component again adds some better support for the IDE and TypeScript. Okay, and one more question by Luca. Do you know if there is any plan to support class style syntax in Vue as well? Class style syntax, you mean like for components definition, I guess. Like in Vue 2, this wrapper for TypeScript, you mean, right? Yeah, no, I have no idea. Honestly, I know this approach like you mentioning with the annotations to make your Vue 2 code, yeah, as typed as possible, but yeah, I have no idea about what is the road map for this now. Okay, good, so now let's, yeah, if there are no more questions, let's move to the data loading part where I will create some more components to showcase the typical setup for loading the data with Vue 3 Composition API. For this, I will need, I will create a simple repository folder which will contain my API calls. For this, I will be just using JSON placeholder demo back-end, so if you never saw that one, check this out. It's a nice tool to play around with some static data, like it has those items that you can just query if you want to just check if your fetch works or if your code works properly, so it just gives us static data. I think it also can give a By ID like this so it can load list and a single item in your code, so I will use these for the demo. So here I just put the base API endpoint and have some fetchers for different types of data. Then I will use one of them for more stuff. Yeah, good point Andrei. As I said, for this I will need to commit the current state. I will do this part of the demo and then I will take care of it, okay? So here we created a repository file which will do a data fetching for us. And then I will create a data load component that will, yeah, basically load the data. I will copy some parts. You asked me again, to create a dataelfecting template, which will do a data fetch. Since I'm gonna be using the user's data, I will use the template of a card that is used in the bootstrap, like a typical, just the blocks with information, and here I will have our component definition. So that's the start, now what we're gonna do, we're gonna create a flag that will, not the flag, sorry, the reactive element that will contain the items, and that will also have the, for example, track the current status of the loading, and then we will also be able to extract all this stuff to for example separate components, and also make use of filtering and things like this. So let's start with a simple version where I will copy the, I will create an object using ref that will contain the data when it's loaded. I will create a function that is loading data. It's called getUsersRepositories. It's a sync function, which is using await inside of it to load the data, right? What else do we have here? We have the lifecycle hook. The lifecycle hook will be used to when component is rendered. It will run the data query. And last, we only will need to return this information, right? We're only tracking the user data, and that's what we want to return currently. So only user data, and that should be, I think I only forgot some markup. Oh no, markup is here. So I'm taking user from user data, and then I show username, user city, and blah, blah, blah. Again, I will replicate a new page. So that we have just more items in the demo that you can switch between. It's now we have a new page called data load and it's already loaded some data. Let's have a look how it's happening. So basically when I'm refreshing the page, there should be a call to the users that returns me the list of failures. And then you have this listing of the users, right. That's pretty straightforward implementation where we are just asking for creating a function that will be doing the synchronous operation and then it will be called during the unmounted part. That's pretty straightforward. So what we may want to do in future, for example, if you have a list of users and we need to search within this list for some extra data, we can do that. For example, we can add ability to search in this list. For that we can, for example, create a search bar on top that will be doing a... We'll be able to do a search of users. Now it does nothing, but we're gonna implement this search.

Implementing Search Functionality#

Short description:

We create a ref to store the search value and implement a logic to filter the loaded user data based on the search query. The search is fully reactive and can be performed on the loaded list of items. The logic uses a computed function to filter the array based on the search field value. The search can be performed both in the loaded list and in the component itself. The example showcases loading data from an asynchronous call to the backend API and implementing search functionality.

So what we have here, we can gain for the search, we create a ref that will be doing the, that will store the value. Now look at this, I created a search variable, a constant in this case, and I'm using it here for a V model, but I'm not returning it, and that's why I also get the warning. Don't forget to return, so, to return it here. So for now, we're connected it to the model, but it still does nothing, right? If I look at my inspector in the, in my view dev tools, I go to data load, I see that I have user data is loaded, all the items are here, and the search is fully reactive, but I don't, yeah, I don't have any logic that actually searched. So let's implement this logic first. We can create, for example, a new list that will store the values, or we can just create a function that will be modifying the existing list. So I'm having this variable here called users matching search query, and it will use a computed function that inside will be doing just filtering against each item of the array. And here, what I'm doing, I'm taking the user data, the values that are loaded during the call to the back end, and then I do the filter, and there's a callback to the filter. I pass this basically a checker that goes into each item and check if its names includes the value of a search field, right? That's a pretty straightforward. Just keep in mind again, the using the value here and using the value here because this is a ref items that need, you need to have this dot value to access its data. Okay? So I am checking now update loaded. Okay, broke something of course because I don't have computed important. That's sad. So I have the list of users loaded initially and now I'll try to search for example, for Path 3, I guess I can, it should, of course I'm taking the value and then I can use this value in my component marker, putting this here. Just for now, I have all the items and then I search for the first one, for example, the Yen, I'm not doing the uppercase lowercase conversion just for the sake of simplicity. So let's keep it as is now. So Yen, you get one item. And if I type some gibberish, it will not show any items. So for, if I use only Lee, I will have multiple items because there are a couple of users with a similar name. So this is a search in the, loaded list of items. What if I do it here? I'll put it like this. And then if I remove this JSON output, I can still do the search here, right? So it works both ways I can load the list and I can also search in it after data is loaded. Okay. So that's a simple example that implements switch off.

Sure, yeah, I thought that it adds some focus, but sure I can disable it for now. Yeah, so that's an example with loading data from asynchronous call to the backend API and searching it. I will keep that screen for a second, maybe for a couple of minutes, just so you can have a look and ask questions if you have, while I will fix the problem with the repository, and then we'll continue, okay? Just give it two minutes, if it doesn't take me longer, and then we'll continue. And meanwhile, please, if you have questions regarding the initial part with the theory, or maybe about the practical samples I'll be showing, please feel free to put them into QA, or type in the chat. So I will get back to you as soon as I'm done with the repo, okay? Also, let's just consider it kind of a quick pause for maybe refilling your coffee, cola, water, or any sanitary activities, okay? But I will show you what we have in the XFDA list, so you can actually use that thing to easily get your drink and water. How we do that is, we put everything into the scanable order and then we upload it to the excusecary. So we get an XFDA list, and the XFDA just puts the details into the scanable order. Okay? So I just fixed that part, and now the sources... sorry, samples folder, does contain all the items that I will be showcasing during the workshop, and maybe even more, than I will be able to show during this show. So please, if you want to follow by looking at the code, please, you can check this URL and clone it and make use of it. Okay? Just if you already forked it, just make sure you pull the latest version. So let's do it one more minute and then we'll continue with the rest of the demo. Okay. So I'm back and let's continue with the rest of the demos. First of all, I wanted to leave some room for the questions about the already shown items like how do we load data, how we create new hooks, and stuff like this. If there are any specific items, please put it into a QA or ask in the chat. I'll try to answer them straightaway. Okay, let's move on. What I'm going to show now is the part about actually using this Vue use library that I mentioned in the slides. It's a really great piece of software that is helpful for making use of a lot of your regular code tasks. And that one I have here in a separate file that I will quickly add to my to my page. Oops... Just a moment... So we'll just use a home page for this experiment just because it's quicker. I will use some of the utilities that few use provides and show how they work in the setup function to do certain changes or access certain APIs. I will comment out the counter now. So first, the one with the CSS variables. So everybody knows what the CSS variable is, right? It's like a, basically, a certain value that is set in the CSS, usually in the root element or the root of the container, and then you can make use of it in other blocks inside of the CSS. Now, a nice part about it is that you can also change it. And that kind of changes in all the context where it's used. So for that, vue.use has a hook called useCSSVar. And it does it like this, you provide it with a name of a variable and a ref link, the element that it will be tracing. So I specifically created the CSS variable here in the root of my demo, a demo index HTML. And for this root selector, I've placed a variable called color and this is using the value of blue, some nice blue color. So we're going to just get access to this variable inside of our component. So I already have it here. So what I'm going to do, I just need to return. So basically those items are partly described in the documentation. So it's more to give you more examples of how you composition API can be used, and also how other custom hooks can be used. It's not something that you cannot try yourself. It's more just examples that you can quickly reproduce. And here I can use the variable color just to show to either set the color actually on the inline style block or just print it out if I want. So now if I'll try that, probably forgot to put something, of course, I forgot the reference. So now you see I have the color and it is taken exactly from the CSS that is here in our style tag. So the color is here and here I see the same value. We can read those variables.

Working with Local Storage and Provide Inject#

Short description:

You can use the hook called UseClip, UseStorage to work with local storage and session storage. The UseTitle hook allows you to change the document title directly from your code. VueUse is a library that provides many useful features. Another feature is Provide Inject, which allows you to provide data at the top level and consume it at a lower level of your application. You can use the provide theme in the root component and the use theme in the child components to access the provided data.

And also, of course, if we want to change something, we can also do that. So if we change the color, then it will adjust the value, and all the rest of the content will be… All the rest of the CSS styles that use the CSS variable will change. That's one.

Another nice item that may be useful for us is working with local storage and session storage. That really works pretty straightforward. You can just use the hook called UseClip, UseStorage. And then here, I created the object called Title, and that will write the value into the specific key of our local storage. And the value will be, for example, from a document title, right? So it can be actually any variable. It can be just some string here, right? It's not bounded to any specific logic for now. It just can be stored here. And now, if I open my app and refresh the page and I go to the local storage, you'll see here the value is already placed. Sorry. I just need to refresh. And search for it. So now, for example, if I take a document title. Then it will put this value into the, into document title. But the nice thing about it is, for example, I want to change the value. There is also a separate hook for this for changing a document title directly from your code. I know it's not something that you do often. But it gives you an example of those modular utilities that you can make use of in using Vue use and similar libraries. For example, I use the hook called UseTitle. And this hook connects document.title to the, to your code. And you can not only read it, but also write it. So here I created the function that will change the value called SetTitle. So I'm importing it here. And now the value will be also written down inside the, inside the session story. So just to showcase that, I will quickly create a function. I'm missing some part. Let me see. And yeah, SetTitle. That's where I also need to put the value. And also when I change the title, I also need to use it here. One moment. Strange. Title saved. Yeah, okay. Sorry for confusion. So what I was doing here, I created a reactive object that will be connected to this specific property, my storage, local storage. And it will initially put this value into it. But then later, if I'm overriding, I can also change the value, and it will be updated automatically also in my session storage. So again, I'm connecting something outside of my component, outside of the app almost, to just some logic inside the component. And I can, again, easily extract this logic to a separate hook and make use of it there. So those are some examples how you can use a library called VueUse. It has much more useful features there, so give it a try. And that's an example that I wanted to showcase specifically about other libraries.

What I also have is another feature that also Vue 2 used to have, but it became much more advanced use in version three, which is called Provide Inject. I think there was also a question about it during the part with the slides, so I'm going to quickly recreate Provide Inject construction, which will be using also a HOOQS API, the Vue 3 API to provide data that will be injected on the top level and consumed on a lower level of my application. For that, I will use this kind of a construction, this kind of syntax, sorry. What I put here, I create like unique symbol, which is bounded to a specific set of details and here I'm calling it Theme because I mean that can be some settings, some visual settings for your application, like default form, default background, maybe title of an application or size of a form, things like this and here I'm creating two functions, two callbacks that I can use to provide some data into the route level component and can take it in the lower component that is down below the list of the tree of component. So this is a typical construction for this provide inject feature and this value here are hardcoded but you can imagine we can take them from some API or from some environment file or whatever and here I only need to use the provide theme in the root component where I want to make use of it. For example here. It's too far. And to be able to add this data about the theme into the context, I only need to call this provider inside of a set up function. And now let's say in one of the child components, the ones that showcase our catalog that I was showing earlier, I can make use of this item to get access to this information. Let's try that. I will now find this component, the child component, and I will just get this data from there. What I will need to do, I will need to import the use theme in this child component. And now for this use theme, I can just put this data that use theme returns into some extra variable, for example, that is returned from a setup method. Let's say theme. And that's it. Then I should be able to access variables from use theme. Directly in the template. Let's first have a look what it has. So you see, now I have all this information, and now I can maybe just make use of some of it. Let's say. Background will be this, and main color will be, for example, the other item that I have there. That is called main color. Like this, let's see if it works. Now, I directly passing... You see, now it is using those colors that I was setting in the theme throughout the list of components.

Using Provide Inject and Custom Hooks with Vuex#

Short description:

In this part, we explored the use of provide inject to pass data directly between components, skipping multiple layers. We also demonstrated how to bind data from a Vuex store to a custom hook, allowing for separation and reusability. The hook uses getters and setters to interface with the store, and we showcased its usage in two components, one for reading the value and another for setting it. The example showed how the selected user's data could be displayed in a header component.

If we look at our view composition, sorry, view dev tools, you see we have several layers and through them we get those data to be passed directly without any troubles. That's an example of provide inject in a nutshell that you can make use of properties, skipping several layers of other components.

What else in terms of other code samples, I think the interesting one is where we can bind data that is stored in our Vuex store to just a custom hook that will be only dealing with this data. And for that, I will be using our previous page with lists of users. And let's say we have a logic that you can select certain user data and then show it somewhere else, right? Something like user data, data of this specific logged in user. And for that, I will create a separate button that will be saving the data of this user. And for this, I will find the right block. So for this, I will need to add to my user list some button that will be doing the selection. Let's see where it is. It is probably, in the data load section here. So I have the users here and let's say when I click specific user, I want to store his or her data in a separate Vuex partition. I will add on click event. It's not, let's say, something like rocket science, but I will just showcase the part with a complete computed object that will be stored as a separate hook and that will provide all the connections to the store. So we'll have a nice separation like a component will use the hook and the hook will use the store. So that they will be completely decomposed from each other. That's why I think it's a nice example to show in the end.

So I created the method select user, I'm importing it here. What I will do here, I will make use of a hook called use user that I'm not going to create. And I created the select user method that will be selecting this specific user, putting this user into this store, part of our VUX store. So that's just a preparation. Of course, I also need to implement our VUX store items to save it and also implement the hook. So let's do the first with the store. I will open our store and add a new property here, it used to have only the counter, but I've also created user data. Then I will create a mutation to actually add the user data into the store. That's pretty straightforward, right? I will also create a getter to retrieve its data. Okay, and this just user data takes this property and that's it. So that's like a preparations, already now what we could do, we could use a component and it will call the VUX and it will do the job, right? But if we want to achieve even more separation, then as I said, we will add a separate hook that will only work with user and then it will kind of be serving that specific purpose and we can have as many hooks for specific data objects as we want. So I'm creating our hook called user, that's of course very useful name to find some better naming, but for now I think that should work. So what I'm gonna do here, I'm gonna again create custom function that will return this user object, right? And inside of it, I will use a store like I did with the counter because that's where the this hook will be connecting to a store. And what I'm doing next, I'm using a compute method. We'll already explained what compute method does, right? It does create a new derived value that will be based on the dependencies of what is provided in the callback, right? But here, so what I was showing before is like this, some callback, and then this callback does stuff that's like the version one. But what I'm gonna be doing, I gonna use getters and setters. That's another API that is available for a computer. So, for this one, you basically provide like for any other JavaScript object, you provide getters and setters that will work with the value of this object. And then you can perform certain logic when this data is retrieved or when it is set, right? And here, guess what? I gonna connect it to the store, all right? And then this will be the connection from the hook to the store and the hook will be used back in the component. That's how the component will never know about the store. So, I gonna put the set, the getter will be using the Vuex getter, right? And the setter, guess what? It will be using the way to mutate the store, meaning it will commit the user data, right? That's the idea. So, we using, a computed object that will have getters and setters that will directly interface with the store. With the store managed by Vuex. And then now, if I want to get this information, let's say have some header component where I want to display a newly selected user. I will just create a simple template. And then what goes next, I will also make use of this hook here. But I only interested in the actual value, so I can even do like this. Which work. I still did not import the user, so I need to do that quickly, otherwise I will have issues. So I'm importing user here, and I'm also importing this user here. Okay. So in one component, I'm using a hook just to read the value. And in other component, I'm using this hook to be able to set the value. And let's see if it's working as it should. I probably, I forgot one important item is to add the header component. Otherwise, it will not gonna work. So we'll import it here. It's magical secret sauce to make sure this part works. So I have a header and then I will just use this header here. Okay, you see here, user is not selected, but what I'm missing here is the button selected. That's probably, C, yeah, it should be just clickable by the whole light. Okay, so you see that it does change, but it does put some pointer event instead of the actual user, it's just can be fixed by calling the function with the proper argument, because here I'm actually expecting this argument. So now I will get the full detail of each user. The one that they click in the subsequent component. Just to make it a little bit nicer, I will put just username. Now, user, let me see there. Because it has another property user in it. Yeah, like this. Or I can even do the use to refs. Right, yeah. So that's also nice part about the hooks. If you don't need all of it, what it provides you, you can just directly put it into your return part of your setup function, and it will be fine. The only thing not to forget is to import the refs here. So, this and then should be user.name.

Demo Conclusion and Migration#

Short description:

By clicking different users, you can change the selected name and filter accordingly. This construction allows for maximum decomposition and the creation of aggregates with different logic. The three dots in the user hook are used for object deconstruction. The terms hook, composable, and behavior are used interchangeably. For Vue 2 users, the Vue Demi tool can support both versions. The migration build, described in the official docs, enables gradual migration by toggling features. Thank you for attending the workshop and feel free to reach out on Twitter for further questions or clarifications.

Yeah, now by clicking different user, you get the selected name change, right. Plus you can still filter and that should also change. So it works with this construction where you have a hook that is only serving a specific part of the store. And that's who is used in several components. That's how you can achieve like maximum decomposition, I would say. And this pattern is also nice. So when you have, let's say, more complex user objects that have many properties in them and different logic, then you can create those kinds of aggregates that perform different activities like with all the getters and setters, right. That's the last demo I wanted to showcase.

So I see a question by Aaron asking what are three dots in the user hook. Let's see. Three dots in the user hook. I'm sorry, I don't see any dots here. You mean, maybe here? Yeah, those three dots are just the same as any JavaScript deconstruction, like when you're breaking objects into pieces. Right. That's that. Like, is it called rest or spread? Spread, I think, right? So it's that kind of thing. It's the same, you would be doing, let's say if you're in, if you're using Burix and you're doing like map actions, then you will have the same. So it's basic JavaScript syntax, it's not some fancy stuff. Okay, this question is done. Yes, probably spread. Yeah, thanks for the, yeah, for clarifications, Steve. Cool. I see one more question from Andre, is the hook the same like composable? Yes, that's, I also said in the beginning, I think there's still different terms used. Hook, composable, behavior. It's all, like, I use them interchangeably. When I was specifically referring to React hooks, I meant React hooks, but that's, yeah. Cool, that's all for the demo. I hope you liked it and again, I will send the link here in the chat so you can try to play with it. Later, just a couple more things to talk about is about migration, so I also remember some of you mentioned that you're using still version two and if you're especially a library author, there is a nice tool called Vue Demi that allows to support both environments, both functionalities in Vue 2 and Vue 3. So you just install the Vue Demi and import all the stuff you need from it and inside of it, it will reroute. So it has like dependencies of both projects, both versions and it will load the right one for you depending on certain settings. That's a nice tooling for if you're using, writing like a library or you already have a library or you have some plugin that you're using and you want it to be able to support both versions until time goes off for version 2. So that's one thing, a Vue Demi and the second is the migration build. It's something that is well described in the official docs. It's like a special configuration that you can put your app in where you can enable features one by one when you're performing a migration of some bigger application, which has many pages, many components, many features, that basically you add a dependency called vue-compat and you replace your version two with version three and then you start basically changing the versions, sorry, start, you can toggle all the features that version three adds and you can kind of gradually rewrite your v2 version into v3 and make sure nothing breaks or at least if you know that something breaks and you cannot rewrite it quickly, then you can disable this feature, right? And then you can continue for some time using version three, but it will be kind of wrapped with this view compatibility build. So that's a nice feature for gradual migrations. I hope those of you who use v2 will have more migrations soon and will have more version three users, and yeah, that's mostly it for my workshop. I'm really happy that you guys stayed till the end. I was fascinated by the amount of questions and I'll be happy to answer more of them if you have now. And if you don't have now or you'd like to clarify something later, please follow me on Twitter. I'll be happy to chat there. So that's it, I also place the links once again here on the slide. And if you have any questions, please feel free to ask. And I hope I answered your questions. Thanks Ricardo, I hope you liked it. I hope you got excited about using Vue 3 and all the composability patterns it has and should make like our life easier and more efficient as developers. Thanks Karen. Have a good evening, if it's already evening for you. Was really a pleasure to share all that stuff with you.

Mikhail Kuznetsov
Mikhail Kuznetsov
169 min
26 Oct, 2021

Comments

Sign in or register to post your comment.

Watch more workshops on topic

React, TypeScript, and TDD
React Advanced 2021React Advanced 2021
174 min
React, TypeScript, and TDD
Top Content
Featured WorkshopFree
Paul Everitt
Paul Everitt
ReactJS is wildly popular and thus wildly supported. TypeScript is increasingly popular, and thus increasingly supported.

The two together? Not as much. Given that they both change quickly, it's hard to find accurate learning materials.

React+TypeScript, with JetBrains IDEs? That three-part combination is the topic of this series. We'll show a little about a lot. Meaning, the key steps to getting productive, in the IDE, for React projects using TypeScript. Along the way we'll show test-driven development and emphasize tips-and-tricks in the IDE.
Web3 Workshop - Building Your First Dapp
React Advanced 2021React Advanced 2021
145 min
Web3 Workshop - Building Your First Dapp
Top Content
Featured WorkshopFree
Nader Dabit
Nader Dabit
In this workshop, you'll learn how to build your first full stack dapp on the Ethereum blockchain, reading and writing data to the network, and connecting a front end application to the contract you've deployed. By the end of the workshop, you'll understand how to set up a full stack development environment, run a local node, and interact with any smart contract using React, HardHat, and Ethers.js.
Remix Fundamentals
React Summit 2022React Summit 2022
136 min
Remix Fundamentals
Top Content
Featured WorkshopFree
Kent C. Dodds
Kent C. Dodds
Building modern web applications is riddled with complexity And that's only if you bother to deal with the problems
Tired of wiring up onSubmit to backend APIs and making sure your client-side cache stays up-to-date? Wouldn't it be cool to be able to use the global nature of CSS to your benefit, rather than find tools or conventions to avoid or work around it? And how would you like nested layouts with intelligent and performance optimized data management that just works™?
Remix solves some of these problems, and completely eliminates the rest. You don't even have to think about server cache management or global CSS namespace clashes. It's not that Remix has APIs to avoid these problems, they simply don't exist when you're using Remix. Oh, and you don't need that huge complex graphql client when you're using Remix. They've got you covered. Ready to build faster apps faster?
At the end of this workshop, you'll know how to:- Create Remix Routes- Style Remix applications- Load data in Remix loaders- Mutate data with forms and actions
Developing Dynamic Blogs with SvelteKit & Storyblok: A Hands-on Workshop
JSNation 2023JSNation 2023
174 min
Developing Dynamic Blogs with SvelteKit & Storyblok: A Hands-on Workshop
Top Content
Featured WorkshopFree
Alba Silvente Fuentes
Roberto Butti
2 authors
This SvelteKit workshop explores the integration of 3rd party services, such as Storyblok, in a SvelteKit project. Participants will learn how to create a SvelteKit project, leverage Svelte components, and connect to external APIs. The workshop covers important concepts including SSR, CSR, static site generation, and deploying the application using adapters. By the end of the workshop, attendees will have a solid understanding of building SvelteKit applications with API integrations and be prepared for deployment.
Build Modern Applications Using GraphQL and Javascript
Node Congress 2024Node Congress 2024
152 min
Build Modern Applications Using GraphQL and Javascript
Featured Workshop
Emanuel Scirlet
Miguel Henriques
2 authors
Come and learn how you can supercharge your modern and secure applications using GraphQL and Javascript. In this workshop we will build a GraphQL API and we will demonstrate the benefits of the query language for APIs and what use cases that are fit for it. Basic Javascript knowledge required.
Back to the Roots With Remix
React Summit 2023React Summit 2023
106 min
Back to the Roots With Remix
Featured Workshop
Alex Korzhikov
Pavlik Kiselev
2 authors
The modern web would be different without rich client-side applications supported by powerful frameworks: React, Angular, Vue, Lit, and many others. These frameworks rely on client-side JavaScript, which is their core. However, there are other approaches to rendering. One of them (quite old, by the way) is server-side rendering entirely without JavaScript. Let's find out if this is a good idea and how Remix can help us with it?
Prerequisites- Good understanding of JavaScript or TypeScript- It would help to have experience with React, Redux, Node.js and writing FrontEnd and BackEnd applications- Preinstall Node.js, npm- We prefer to use VSCode, but also cloud IDEs such as codesandbox (other IDEs are also ok)

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

Don't Solve Problems, Eliminate Them
React Advanced 2021React Advanced 2021
39 min
Don't Solve Problems, Eliminate Them
Top Content
Kent C. Dodds discusses the concept of problem elimination rather than just problem-solving. He introduces the idea of a problem tree and the importance of avoiding creating solutions prematurely. Kent uses examples like Tesla's electric engine and Remix framework to illustrate the benefits of problem elimination. He emphasizes the value of trade-offs and taking the easier path, as well as the need to constantly re-evaluate and change approaches to eliminate problems.
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.
Welcome to Nuxt 3
Vue.js London Live 2021Vue.js London Live 2021
29 min
Welcome to Nuxt 3
Top Content
Nux3 has made significant improvements in performance, output optimization, and serverless support. Nuxt Bridge brings the Nitro engine for enhanced performance and easier transition between Nuxt 2 and Nuxt Read. Nuxt 3 supports Webpack 5, Bytes, and Vue 3. NextLab has developed brand new websites using Docus technology. Nuxt.js is recommended for building apps faster and simpler, and Nuxt 2 should be used before migrating to Nuxt 3 for stability. DOCUS is a new project that combines Nuxt with additional features like content modules and an admin panel.
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.
Utilising Rust from Vue with WebAssembly
Vue.js London Live 2021Vue.js London Live 2021
8 min
Utilising Rust from Vue with WebAssembly
Top Content
In this Talk, the speaker demonstrates how to use Rust with WebAssembly in a Vue.js project. They explain that WebAssembly is a binary format that allows for high-performance code and less memory usage in the browser. The speaker shows how to build a Rust example using the WasmPack tool and integrate it into a Vue template. They also demonstrate how to call Rust code from a Vue component and deploy the resulting package to npm for easy sharing and consumption.
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.