New component patterns for Vue 3

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
- Today, we'll be talking about some really cool features from Vue 3. Vue 3 offers us so many new things. The most famous feature in Vue 3 is probably the conversation API. It allows us to write our components at different syntax while offering what code usability. However, there are a few other new synthetic format that we can use to create our components in Vue 3. These lesser known patterns are a bit different from the standard composition API and classic options API. In this video, we'll be exploring three of them. These are the three syntactic patterns we'll go over. We'll go through the pros and cons of each. I've also rated each of them against a set of criteria. Don't worry, I'll explain each one of these ratings and my reasons for them. If you want to follow along with the code, make sure that your app is running Vue 3. You can create a brand new Vue 3 app using Vite. We'll also be doing some TypeScript stuff. So you will need a TypeScript app to follow along. All you have to do is to change the template year with view, dash, T S. Now that we're ready, let's jump right in to our first pattern. Hybrid means to mix two different types of APIs together, the options API and decomposition API. You can keep most of your code in the options API and still benefit from the co-sharing features of the composition API. Let's apply this hybrid pattern in a component. We're starting with the brand new app. Here I'm going to paste in some code. It's a component written completely in the classic options API. It shows a count and we add one to the count every second automatically via the timer. There's also a button for resetting the count. It will trigger the reset function, which is defined down here. Now let's assume that this automatic candling logic is needed across multiple components, not just this one component. And that's exactly the kind of problem that the composition API is meant to solve. Let's see how we can tackle this. First, we can extract the automatic canning logic to conversation function called useAutoCount. Copy this and put it here. Make it assigned with the ref. Next, we also want to move this lifecycle hook to decomposition function. We'll create a same lifecycle hook, but it's called onMounted instead of mounted. Let's show that it's important up here. My IDE has done that for me automatically. And we can move the code from here to here. Now we can remove this and let's go ahead and remove this as well. Since we're using ref, we have to import it up here. There are still a couple of things we have to do. Change this to count dot value and we have to return count. Now our component is missing the core logic. So it's not even working at this point. What we have to do is to first create a setup function, and we can call the use auto count function in here. And this will set up the automatic counting logic for us. Lastly, return to count so that the template can access it. The count goes up automatically and we can reset it as well. Now to improve this, we can add the parameter to this composition function, and we'll use this parameter as the initial value for the count. So now we can decide which number to start with right inside the component itself. Now our component is using both decomposition API and the options API. And we also have the freedom to store this composition function in a separate file. Let's do that now. First create a folder and the file for this function with the same name and go back to where we were, copy the function including the impost statement, put it in a new file, and make it the default export. We're done here. We just need to go back to your out component, and import the new composition function. And we're done. Not only that our component file is cleaner, we can reuse decomposition function in another component the same way we did here. This hyper syntax is a perfect way to use the composition API in your existing code without a major refactoring. Now let's take a look at a ratings for the hybrid pattern. Versatility refers to quality of being able to do many things. This hybrid syntax has all the powers of decomposition API. You can think of it as a special version of the composition API where the life cycle methods and even handlers can be defined in options instead of the setup function. Compactness means that the components part can be brought together in a coherent fashion. Since we're mixing two types of syntactic structures our code doesn't look coherent. For example, inside the setup function, we're referencing the counts date as simply just count. But in the reset method we're using this tag count. Type script friendliness is about ease of using TypeScript under a particular components syntax. This is not the same as TypeScript support. UGS has TypeScript support for both the options API and the composition API. However, under either one of these APIs, it's not that friendly to work with props in TypeScript. UGS provides dynamic runtime type checking for props, and that's a built in feature of UJS. This building tight checking clashes with the static compiled time type checking of TypeScript. Let me show you what I mean. Here we have a TypeScript version of the same app that we've been working on. In order to make TypeScript compatible with views built in runtime props type checking. We have to resort to syntax like this. This object type is used as a place holder in views building type checking system or using this prop type generic type as a workaround to make props compatible with TypeScript. This is not the most friendly TypeScript experience out there. That's why I'm giving it a two-star rating. So basically the conflict here is that if we want pure TypeScript annotations, we have to give up this props option that we're so familiar with. To get a glimpse of how to solve this problem let's take a look at a functional components syntax. Previously in Vue 2 this is how we create a functional component, but this syntax has been deprecated. This functional attribute is no longer supported in Vue 3. Now let's take a look at how we do that in Vue 3. Back in our app component. How about we extract this part and make it a functional component. First create a new file. In Vue 3 a functional component has to be a pure function. As you can see, we're not getting any syntax highlight. That's because our file has the dot you extension. What we need is to pure that JS extension. Let's change this to an assignment. This is more conventional. To define the props in this functional syntax we have to use the props property of the function itself. Just like the options API, we can also define the prop with it's type. And make it required. At this point, you might be wondering, how are we going to use template with this functional syntax? We cannot use template here. We have to use the itch function instead, this is an alternative to template. We use this to describe the Dom structure of the component. It's going to be a P element for the class attribute. And finally, he will contain the camp that we passed through to props. And we have to make the props available as a parameter of the function. Let's do an overview of this function. It takes three arguments to create an element. The first one is name of the element as a string. This can also be a component. The second one is an object of attributes. This is optional. The last one is the child element or children as an array of child elements. The equivalent of this in templates syntax will be something like this. So we're able to create elements inside the functional component. You might be wondering what else is allowed. We can use ref. We can also use reactive, but there is a catch. We'll talk about this in a bit lifecycle hooks are not allowed inside the functional component. Again, I'll talk about this in a bit. It will all make sense. However, we can still create callback functions here. Let's set it to the click event at the P element. We can do this with the on click attribute. And since the function has the same name, EA6 allows us to have on click here just once. So we don't have to do on click colon on click. As it stands is functional component looks a lot like a simplified version of the composition API. Next, let's go back to the app component and import our new functional component. Register it with the components option. And now we can go to the template and we place this without new component and passing in a prop. We can check it out in the browser. We can confirm that we're indeed rendering our new functional component because of the class that we added. Now let's switch to TypeScript. We're still defining the props the same way that we did in the hybrid syntax. With dysfunctional syntax we can also define the props in pure TypeScript annotation. We're going to do that in the parameter. Now we don't need this. Since this type annotation is just TypeScript we can extract this and create custom interface for the props. And use the interface here. Now let's take a look at the ratings for these functional syntax. You might be surprised by this one-star rating, but this is justified by two deal breakers. First functional component has to be stateless. That means he cannot have state. Remember that I said you can use ref and reactive, but there is a catch. The catch is that when you change a state of any one of these reactive variables, the component is not going to get re rendered. Let's do an experiment. Change the value of the ref in the on click callback and lock the result. Let's create an additional element to rendered X value. And put the on click event here instead. Now go to a browser, even see the X value is rendered here. Lets also open the console. When we click on this X element, you see it's updated value getting locked to the console, but the element itself did not get re rendered with the updated value. It doesn't matter how many times you click on it. It just stays the same. The second problem is the complexity of this render syntax. It might look acceptable in our code here. But if you want to do something more elaborate such as rendering with the loop, it can get tedious to write. It also kind of defeats the purpose of using Vue JS. So one star for versatility. And you should only use this functional syntax for components that are stateless and simple. Next three stars for compactness because there's nothing more compact than having everything all inside one function. Lastly, TypeScript friendliness is still two-star. Let me explain. Even though we're able to use pure TypeScript annotation in this syntax, there is a drawback that comes with it. There is no building support for defining default prop values. We can still do it with some Home brew trait, but it's just not very friendly. First, make the cam prop optional, then rename the props parameter to something else. As soon as it got renamed, we'll see this error. We just have to create another variable called props. In here we will set the cam prop value conditionally. If it's not defined, we set it to the prop that got passed in. If it is undefined, we set it to the default value. As you can see, we need all this additional code just to set a default value for prep. It's not very friendly. I think it's a good time to do a recap before we move any further. On one hand, we have this hybrid syntax that offers great versatility, but it's not compact. On the other hand, we have the functional syntax as is probably the most compact format ever, but it's not versatile. It only works for components that is stateless, and you can not use template with it. And both of them have their own moments of TypeScript unfriendliness. So heres back to the question: is there a component of syntax that is versatile yet compact and also friendly to you when you're using TypeScript? And the answer is yes. And we'll get to that right now. Script set up is a new feature in Vue 3, it became an official feature in Vue 3.2. It's basically just a simple way to create components with the composition API. For example, let's take a pure composition API component like this one here and refactored with the script set up syntax. First extract, a set of function. Notice that all the important code is inside is set up function. The code over here is really just metadata. We can just get rid of it. All we have here is basically just one function. The scripts set up syntax allows us to have the content of dysfunction to be on the top level of this script tack without the function wrapper. But we have to add the setup attribute here to let view, know that we want to use this script set up syntax. The import statement have not changed. And finally, we can remove the return statement because we're no longer inside the function. Vue will automatically make all the variables in this scope available to the template. Notice that using this syntax doesn't affect our code in a template, but as a convention, we're going to place the template below the script. And we're done. Here's a before and after comparison. Basically, we just took the content of the function and put it directly inside the script tag and got rid of everything else. Next, let's talk about how to define props in this new syntax. We just have to use a new function called define props. It takes the same old props configuration object as the argument. Now let's turn to TypeScript. Next to the setup attribute we're still using the Lang attribute the same way. Instead of defining a props like this, we can also do it with the pure TypeScript annotation. Let's first remove this. We're going to use the generic angular brackets to define the props type impure TypeScript. And of course we can extract this and create a custom interface. And use the new interface here. Next let's talk about the second props problem that we had. How to set default values for our props. First, make it optional with the question mark. As soon as we did that, we get this error. With the user, not a function called with default, and we can pass an object as the second argument. Here, we can define the default value for our prop. And we're done. Now you're probably curious about as two functions, we didn't import them, so where did they come from? These functions are called compiler macros. They only get executed in compile time. And because of that, they don't need to be imported like other functions. And I should also mention that the compiler macros can only be used with the script set up syntax. This script set up feature was implemented using the compilers centric strategy. The code we have here will get compiled into a different looking runtime version. We can confirm this by going to a browser open the Def twos, select the app component here. As you can see, the runtime code is very different from our original code. We don't even see the two compelling macros that we used. Finally, let's take a look at a ratings for the script set up syntax. In the script, set up syntax, you can do all the things that you could do with the regular composition ABI syntax. That's why it has the same three-star versatility as the hybrid syntax. We're able to work with the script tack as if it's the setup function itself. So his script tag is now practically just a function and we don't even need the return statement. That's why it has the same three star compactness as a functional syntax. With the help of compelling macros like defined props and with default to streamline everything. It's not hard to see why this is the most friendly TypeScript experience in the Vue ecosystem. The script set up syntax is now officially recommended syntax for using the composition API in Vue 3, but the other two patterns can still be useful depending on your unique use cases. Also, don't forget that you can still use the classic options API. I hope that you've learned something useful that you can apply on your next project. To continue learning, you can check out my full course on TypeScript with the script set up syntax at vuemastery.com. Along with the library about a premium view courses. Thanks for watching!
Info
Channel: Vue Mastery
Views: 15,385
Rating: undefined out of 5
Keywords: vue, vuejs, vue js, vue 3, vuejs 3, vue.js 3, vue js 3, vue3, vue tutorial, vue js tutorial, vue 3 tutorial, vue.js 3 tutorial, vue js 3 tutorial, vue3 tutorial, learn vue 3, vue mastery, composition api, vue composition api, vue.js composition api, vuejs composition api, vue js composition api, vue 3 composition api, vuejs 3 composition api, vue js 3 composition api, vue 3 script setup, vue.js component, vuejs component, vue js component, vue 3 component
Id: SMGdokqKEuY
Channel Id: undefined
Length: 21min 12sec (1272 seconds)
Published: Thu Oct 28 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.