Building Vue forms with VeeValidate

Recording available for Multipass and Full ticket holders
Please login if you have one.
Rate this content

In this workshop, you will learn how to use vee-validate to handle form validation, manage form values and handle submissions effectively. We will start from the basics with a simple login form all the way to using the composition API and building repeatable and multistep forms.

Table of contents:
- Introduction to vee-validate
- Building a basic form with vee-validate components
- Handling validation and form submissions
- Building validatable input components with the composition API
- Field Arrays and repeatable inputs
- Building a multistep form

VSCode setup and an empty Vite + Vue project.

176 min
27 Oct, 2021


Sign in or register to post your comment.

AI Generated Video Summary

This workshop focuses on building forms with VValidate, a popular Vue.js form validation library. The workshop covers the basics of VValidate, including field validation, form validation, and form submission. It also explores advanced topics such as using the composition API for form validation, handling field arrays, and using VValidate inspector and V-Validated VTools for debugging. The workshop emphasizes the flexibility and ease of use of VValidate, as well as its integration with other Vue.js libraries and UI frameworks.

1. Introduction to VValidate and Building Basic Forms

Short description:

This is a workshop for building VForms with VValidate. We will have a short introduction to VValidate and what changed from version three to version four. We will also build a basic form with VValidate components and handle submission needs. The composition API and field arrays will be covered. We will put all of this together to build a multi-step form from scratch. VValidate is the most popular Vue.js form validation library. It has a certain philosophy when it comes to validating fields. We will be using an empty Vue.js Vite project and TypeScript with setup script syntax. The API has changed between major versions to address issues with state and V-model detection. The new API provides more flexibility and solves previous design flaws.

Okay. Hello, everyone. This is the workshop for building VForms with VValidate. So this will be a short intro and we will get right into it.

So a little bit about me. I am Abdurrahman Awad, a front-end engineer at Octopods. I created and maintained VValidate since 2016, so it's been five years now. I usually write about VJS at my blog,, and I do from time to time talk about VValidate there. So if you are interested in that type of content, check it out. Also, you can give me a follow on Twitter at logarithm.

So what do we have for today? So for today, we will have a short introduction to VValidate and especially what changed from version three to version four because there is quite a lot of changes. Also, we will be building a basic form with VValidate components. We will handle the basic or most of the submission needs, like when you should handle submissions, how you should handle submissions, and the various tricks that you can apply there. So also, we have the composition API because V3 came up with the composition API, and it is a really exciting API that you can use and it will really help you stay productive in your application. So VValidate has first-class support for the composition API, and we will be taking a look at that. Feel free, first, before I get into more of this, use the chat to ask any questions. I'm constantly looking at it. So if you have a question, type it there, and I will try to answer it to the best of my ability. So we also have field arrays, which are really complicated type of fields. They are fields that repeat, like users can repeat that type of field multiple times, like multiple forums or multiple email fields, stuff like that. So we'll be taking a look at that as well. Also, we have the div tools, and we will be finally putting all of this together to build a multi-step forum from scratch or from what we will be typing down there. Okay, so before we start, if you are not familiar with VValidate, let me give you a few numbers. So currently, it is the most popular Vue.js form validation library. There are a couple of more very popular ones, like VValidate, but VValidate currently is the highest one in terms of downloads and starts in GitHub. So you are in a very good company if you decide to use VValidate. VValidate has a certain philosophy when it comes to validating fields or how you should validate fields. So if that philosophy doesn't work for you, it's fine. You can use any other library. They all do their job just fine. So let's get into it, and we'll be typing code this entire workshop, so no more presentations.

So what I have here is an empty Vue.js Vite project. If you are not familiar with Vite, I suggest that you check it out. It's a really cool way to build your new Vue 3 apps. It's really fast and allows us to really get quickly typing down, mocking up some projects, and yeah, it's really nice too. I use it in production. It's really nice. So a couple of things before I start here. I will be using TypeScript, but I have turned off the strict mode, meaning I will be mostly typing JavaScript. I won't use TypeScript-specific syntax. So if you are not familiar with TypeScript, don't be worried. I'm just using it to give us hints into what functions and methods are available on the APIs that we are going to use. Also, I'm using the setup script syntax. This is new in Vue 3.2. It allows us to be really, reduces the verbosity of our code. It will make our code really simple and will reduce a lot of the noise that we usually have. So I won't get into the details of these things. So follow along. And again, if you have any questions related to these syntaxes and the setup script, let me know and I will answer them. Okay.

So let's get started. So if you already used V-validate before, you already know that it changed from like each major version has its own API, and it changes dramatically from one to the other. So starting with version two, so V-validate version two, you had the directive. So you had this input tag and you just added a V-validate tag on it, and you just added some rules like required email. Right? But with version three, it changed, and now we have to use a component called the validation provider. And it still looks kind of similar, but it's like we swapped the directive for a component, but the API is very different. Like you have a component, a higher order component, and before that you had a directive. With version four, it is similar, but you have instead a field component that functions similarly, but not quite the same thing. So I'm just going to give you like a trip down the memory lane, and I will explain why these changes were necessary. So with version three, the directive was a bit problematic, because the directives in Vue.js are stateless, meaning they don't have state, they don't have instances, which meant maintaining the state for each field was a very difficult task, and that produced too many bugs to handle, and eventually I thought I can no longer maintain that API, because it's just a flawed design. So we moved to higher order components, because components have state, they can have their own life cycle, so I have a lot of freedom here to expand the features of V-validate there. So that's why we moved away to higher order components. But again, there was a design flaw here, which relied on a view internals, which is the detection of the V-model. So with the detection of the V-model, it relied that the validation provider can locate the node that has this V-model. So if we had a div, and the div had this input, V-validate will go down the tree trying to locate this V-model field. Oh, we have a question chat. Native HTML support. That doesn't work with V-validate, you have to use JavaScript now to actually drive validation. That used to work with with V3 and V2, but no longer works in version 4. Okay, moving on. So for the validation provider to work, it needed to find this V-model, and when it didn't, that caused problems. For example, if you are using Vue.tify, which is a very popular Vue.js library, and it had its own menu components, input components, and these components can combo into each other. Like you could have a V-menu field, sorry, a V-menu component, and that V-menu component could have a V-model on it to toggle if the menu is open or not. So it's open, for example, and you had a V-input or a V-field here, and both had V-models. So it was similar like this, not quite like this, but it was similar. If you use date breakers, that exactly was the case. If you didn't, then this might look weird for you. But anyways, that means we have two V-models. So this confused the validation provider. It was no longer able to know which node should be validated. And we know computers are dumb, right? We have to tell it everything. We have to tell, yeah, this node should be validated. So this design was flawed in that regard. It was very hard to let the validation provider know which node should be validated and which one should not. So that API was really hard to maintain as well. And actually in Vue 3, there was a lot of internal changes, which made it impossible to even detect the V-model on a certain node. So V-validate could no longer know if a node has a V-model or not. So that forced us to come up with an entirely new API. So if you are frustrated, kind of disappointed that the API didn't carry over without breaking changes, I'm sorry, but that's what happened. So now we have a little bit more context into what happened between the releases.

2. Introduction to VValidate and Basic Form Setup

Short description:

Version 4 of VValidate is inspired by existing front-end libraries and provides a good API for Vue applications. Let's start by discussing normal HTML forms and how they can be replaced with VValidate components. By replacing the form and input elements with the form and field components, we can create a VValidate form that behaves the same as a native HTML form. This allows for easy migration from native forms to VValidate. The field component renders an input field by default, preserving the same HTML API. Now, let's talk about validation. The first method we'll cover is using the rules property to validate fields.

So version 4 is very different because it is inspired already, like it's not a complete new thing. It's already inspired by a lot of existing libraries in the front-end space, like Formic in the React world. There is also React Final Form and a lot of other libraries. So it takes some inspiration from a few Angular libraries, a few React libraries to get a really good API that proved itself in the field of production apps and loved by many developers into your Vue applications. So this seemed like a good way to start and to see what we can do and how to provide validation for your applications, your Vue.js applications.

So, okay, so let's get right into it. Let's first talk about normal HTML. So you usually have a forum and that forum always has a few inputs. So let's make a very basic signup forum, for example, or a login forum. This would be the email. And we have another one for the password. So this is like the most basic form you can have. Of course, you could have also a submit button. And that's it. That represents entirely all of your forums, but in a very basic sense, without any styling, without any kind of fancy components. So let's first see how does that look like. Let me try to look at the browser. Okay. Yeah, I haven't run the server, so. Okay. So this is how it looks like. Nothing fancy. Very straightforward. We try to type some stuff into the forum. Obviously, there is the native HTML validation that's going to run because we have to set the email field as a type of email. So it will be validated as an email. So if we respect that and click submit, you'll notice there is this weird behavior. It's not weird. It's how forms generally work. You'll notice that we have this URL, which has the values of our own inputs from the last time. This is the native form submission, the default one. When you submit a native form, the default one, when you submit a native HTML form without any kind of attributes, it submits it to the current page and it will take the values and apply them as query parameters into your URL. And it will reload the page. So a lot of developers use this with different attributes. For example, you won't have this. Most of the time, you won't have this. You'll have something like you'll add a method. So something like slash login. And I'm sorry. You'll have a method called post and you'll have the action pointing to the endpoint that you want to submit to. So this is more like what you will have in a typical back-end application. Like if you have Laravel, if you have Django, if you have any other kind of back-end application. So if it's server rendered, this is usually what you do. And you basically replace these elements with your own components to give them the styles, to give them whatever requirements that you need. With VValidate, it's not different. So let's remove these because they are not relevant here to our use case. But so with VValidate, it is straightforward. We have a couple of components that you will be working with most of the time. So you have the field component and you have the form component. This can be confusing. For example, a lot of other component libraries can have the same name. A lot of other component libraries can have the same name as form. And we actually have form as a native element. So this could confuse you. So be sure to actually rename this. So for example, something like vform, if you want to really make it unique. But personally, I don't see like there is a convention. Like if the text starts with the uppercase, then it's a component. Otherwise, it's a native HTML element. And that works fine in Vue applications. But if you are using VValidate and Vue.js in the CDN, you need to be careful about that because everything is under case. So be sure not to confuse it. So first thing we can do is replace the form element with the form component, then replace the input element with the field component. And that's it. Now we have a VValidate form. Of course, it will look the same. It will behave the same. Nothing really fancier. So let's clear the square parameter and see how it works now. So when I submit this, nothing changed. It's the same exact behavior. And this can be confusing, but also can be a blessing. Because that means if you have like a native HTML form, you can easily migrate to VValidate by just doing these small replacements. This is the promise of VValidate's promise to be a progressive API, meaning you can apply it incrementally when you need it. And when you don't, then you just don't apply it. So similar to the same Vue.js ideology of it being a progressive framework where you can sprinkle some widgets, components across your app to just give it enough interactivity that you need. You don't have to render the entire thing with Vue.js and Vue router. You don't really have to do all of these things. So VValidate tries to follow the same principle by being very minimal and mirroring the same HTML API. So the field component actually renders an input field by default. Same thing for here. So it will just render. It is completely equal to this. So this is by default. So you won't lose anything. Now let's get to the important part. So where is the validation? Well, validation, you will have to validate the fields. You have multiple ways to do so. So we'll start with the first one, the first one being the rules property. So you have this rules property that you can apply to your fields.

3. VValidate Field Validation

Short description:

VValidate can accept a function to determine if a field is valid. For email validation, it's necessary to check if the value is present, not null or undefined, and not an empty string or just empty spaces. Then, the email can be checked using a regex or a string validation library like Validator.js. The validation function can return a string as an error message. The password can be validated in a similar way.

And you can tell VValidate what to do with each field, like when each field should be valid. So this can, at its most basic level, it can accept a function. So we can create a function called ValidateEmail, for example. The validation functions always take a value. So they take the current value of the field. And it's up to you to decide if it's valid or not. So for an email, it can be a little bit hard to determine if it is valid or not. So we'll have to hunt down the regex and use it. But for now, let's just make a very basic thing here. We need to check if it's there first. So the value isn't null or undefined and not an empty string. And it's not just empty spaces, right? So that means they did enter like a full length or a non-empty string. Then we can check if it's an actual email. Checking if it's an actual email or not, again, is tricky. You have to find the regex and use it or use another library to import like a validation, string validation library, like Validator.js. I will try to show you that. But for now, let's just, this ignores this for now. So to do here, validate if it's an email. Otherwise, then it's not really a valid email, right? So this field is not a valid email. Notice that here I return the string. So if you return a string from your validation function, it will be used as an error message. So let's use that there and let's validate the password similarly.

4. Implementing Validation Logic for Forms

Short description:

We validate the password by checking if it's not empty and if its length is at least six characters. For the email, we temporarily treat it as a string until we add the validation logic. We display error messages using the error message component. To validate the email, we use the validator library's is email function. Validation occurs on change, not on input.

So, okay. Again, we will take the value. We will probably check if it's not empty as well. You can clean this up. So if, but here let's check if it's, so if it's there and there is a, there is like, it has an actual length, then it is valid. So we can return true in that case. Otherwise we return password is required. So yeah, we are basically testing for required here. Maybe for the password, we need to check if it has more than, let's say, six characters, but that will be confusing, right? Because that will say that our password is required. While they might have entered something less than six. So do the, we have a question here. Do the rules from V3 still exist? Yes, they still exist, but they exist as a, under a different terminology called global validators. I will show them up next. Yeah. Okay. So let's clean this up a little bit because this is confusing. So let's check if the, first let's check if it exists. So this means that right up until this point, this field is, has a nomenclature string. So let's flip that actually. So if it's not, so it's either an empty string or null or undefined, we will show this password. Otherwise we can have our other check, which is value to trim. We are using trim to remove any white spaces that the user might have added, but yeah, it's not really necessary. Just for example, secure. So we, we need to make sure that the length is actually bigger than or equal to six or five. It doesn't really matter. That means it is valid. So flip it again. This is a really nice practice. You should start with the invalid conditions. So if it is less than six, we can return another error message. And let's say password must be at least six characters. Eventually the field is considered valid, right? So we'll just return true here, and that should be it for the password. We are now validating the password. For the email, again, I said this is tricky, so we will just ignore this for now. We'll just make sure it is, it has a string temporarily until we actually add the validation logic for the email. So without out of the way, let's test what we have right here. So when I reload this, let me clear the query string up there. Let's see if it submits. And let me type something, invalid, something like this. First, it will trigger submission again, right? So it's still submitted, even though everything is invalid. Well, this is because, so you can check this out. We didn't really prevent the email from being submitted, even though it is a valid email. And I think I did write a valid password. So let's try this again with invalid password. Again, I should remove this to not confuse us. So, and if I click submit, notice that the URL doesn't change. That means it is not submitting, but we can't really see any errors, right? It's not super clear what's going on here. This is because we haven't really displayed the error messages. So you have multiple ways to do this. The easiest is to import another component called error message. So this component, you can just put it down a field, give it the same name as the field that you are trying to show the message for. So we'll repeat that for this one as well. Click save, reload, and let's try again. So we have this, again, the email is not validating properly yet. So once I clicked outside, I noticed that it did validate and it said the password must be at least six characters. Let's clean our markup a little bit, because it can be hard to see the error messages. So I'll just put them inside the box using the element. And yeah, it's a little bit nicer now. So again, if I type invalid password, it says password must be at least six characters. We are not validating the email yet. So let's get to that. So again, you want to validate an email, you can hunt down a regex from Stack Overflow or whatever, but you should really be using a library that does the job for you. So you can add the validator.js library, which does string validation. So start server again. So right here, let's see what the validator.js actually has. So it should have like a slash email. It seems like I have installed the wrong library. So let's look it up quickly. Again, sorry about this, but yeah, its name is validator. It's not. Yeah, it's validator, not validator.js. So okay, so let's fix that. From validator library, we should be getting an is email function. Yeah, so we have this is email, and we can import it as email like this. And we can now check if it's an actual email, but we want to check first if it is required. So let's flip these conditions again, similar to the password. So we are making sure they did type something. Otherwise, we will have to tell them email is required. Then we need to check if it's an email using this library. And we can then, if it's not an email, then we can return this message. And here we can say it is true. So let's go back to the code right here. Let's type something that shouldn't be an email. So yeah, we got that right. If we try to clear it entirely and click outside again, it says email is required. So when does validation occur here? The native or the default behavior for the field component is it validates on change. It doesn't validate on input. So whenever you change the input by leaving the field, blurring it, for example, it will validate. So by default, it is not aggressive. And this is really like a lot of people really want that a lot, most of the time.

5. V-Validate Form Validation and Submission

Short description:

V-Validate allows you to customize validation and validate in real time. It adapts to your use case and allows you to handle form submission using synchronous calls to the backend. V-Validate introduces value tracking, eliminating the need for V-Model and making forms more declarative. By listening for the submitted event, V-Validate disables native HTML submission and provides access to the form values.

So you can actually customize this, and you can tell it to validate on input. And since it is a Boolean, we can just leave it like this. Reload. And yeah, now it validates almost real time. Right? So this is a small thing. Again, I'm not going to dive deep into the API of each component, because there are a lot of options and a lot of configurations that you can do. So yeah. Now that we if we try to click submit, it will validate the password. It's not valid. Now it is. And once we fix the email, the form now submits. And it will submit using the same native HTML method by reloading the page and appending the query parameters up there.

Now, you may not always need this. And usually, us Vue.js developers, we don't really want this to happen. Right? We always prevent the submission of the form. So because we prevent the submission of the form, we want to handle the submission itself using synchronous calls to the backend, using AJAX or Axios or whatever synchronous request library that you want to use. So we validate it again. It doesn't do this by default for you, because it can't assume your intention. Like it can't tell which way are you trying to submit it. Maybe you're a backend developer that just wants to add some error messages on the client side. So it shouldn't really assume that. But it really adapts to your use case quickly. So let's say we want to add a submission function. Right? So you can have a submit event. And let's call it on submit. So this is where we want our values. Or what we want to happen when we submit. Right? Okay. So we didn't talk really about values. Right? Let me collapse these. So we didn't really talk about values. Where are they? Right? Usually in Vue.js you have the model. Right? And that usually is bound to something in your data. But it's not the case here. This is because V-Valid has this new concept of value tracking. So ask yourselves usually, first before I continue, which version of V-Valid should we install? Yeah. Sorry, I didn't clear this up. If you are installing V-Valid, you need to ensure that you're like installing version four. Right? So version four is tagged as next, similar to Vue.js. So this can be confusing a little bit. But since Vue.js, Vue 3 isn't exactly the latest release and it's still tagged as next, you still have to, I'm doing the same for V-Validate so you don't install the wrong Vue version with the wrong V-Valid version. Because you can end up installing the V2 with V-Validate 3 and 4, sorry, and the vice versa. So if you are following along, make sure to install the add next release. It should give you V-Validate 4.5. And you should be using Vue 3. Again, V-Validate version 4 only works with Vue 3. It doesn't work with any previous releases. So the migration path is very hard and I'm sorry for this. So where was I? Right. Submission. So V-Validate has this concept of value tracking. It tries to do the value tracking for you. So you don't have to, like you usually would have done something like this. You would have exported the component object, right? And you would have this data and then you would have your email field, for example, and you will have this password field, right? And then you'll go to your inputs and you will bind them to your data items, right? Now, I don't know about you, but personally, as a Vue.js developer who built a lot of forms and many dashboard applications, admin dashboards, form wizards, dynamic forms, always using V-Model was really hard to scale up. It's really nice for starting with simple forms and it's really nice for a lot of use cases, but after a certain point, it becomes really hard to maintain. Like, for example, if we added another field to the form and let's say it's a name field, right? Now, this becomes annoying because I have to go down here, add the name binding, go up here at the V-Model for the name. And we didn't even handle submission, right? Like, in submission, you will have to, if you are using Axios, for example, you'll be doing something like and then you will give it the URL right here. And then you will write some, the data items themselves. So, you'll have emails, email, and so on. So, so this becomes really annoying, right? You have to go, like, you have three places now. You have the template, you have the data, and you have your methods. So, this is really hard to go back and forth between two and really takes a lot of your time. And usually, you would like your forms to be declarative. This is the beauty of the HTML native API. Your forms are declarative by nature. Once you declare a field, that's it. That's the state, that's everything done in one go. So, sadly, when we move our forms to JavaScript, we kind of lose that. We kind of lose that because of the V-Model. The V-Model isn't bad. It's like one of the greatest Vue JS features. It makes V-Model really great, but it doesn't scale well if you have a lot of things going on in your form. And if you have a dynamic form, it can be really hard to deal with. So, let me remove all of this code. So, what V-Validate tries to do for you is I will complete this thought and I will answer the questions here. I will try to answer questions every few minutes so I don't break the flow of things. So, please be patient. Okay. So, V-Validate tries to do this for you. Okay. How so? Well, since you have a method that you are trying to listen for, you are now trying to listen for the submitted event, right? So, V-Validate does two things for you. It now knows, yeah, you are trying to hijack the submission using JavaScript. So, I should disable the native HTML submission entirely. Usually, in your Vue JS application, you have to do this, right? Add, submit, dot, prevent. You don't have to do this with V-Validate because it knows. It knows you are trying to handle it with JavaScript, so it will prevent it for you. And then it passes you something, some stuff that are really useful, like the values. So, it gives you the entire values of the form. So, let's see how does that look like. Maybe I will try to alert it.

6. Form Submission and Field Customization

Short description:

We can use JSON.stringify to make the object look pretty. The submission process works without setting up V models or data items. Adding and removing fields is easy. The field component can be used with other libraries. Custom components can be rendered with the field component. The extended syntax allows for more flexibility in styling.

And let's use JSON.stringify to make it look pretty. And we'll have, this is just the syntax of JSON stringify. It will print the object in a really nice way. Yeah, we have now submission. And I forgot to run server again. Sorry.

Okay. Okay. Now we are set again. If I try to submit, it complains because everything isn't valid. Then we have the password. It doesn't really matter which password because it's just an example. And once I click submit, notice what happened. First, the URL didn't change. Secondly, it alerted the input values for us. Like, it alerted an object containing the input values. And we didn't have to, like, set up any V models or any data items, right? All we had to do is this.

So, I just want to add another field. Let's add that name field again. And it won't have any validation. So, we'll just remove that. It will be a name field. Of course, it will have the type text. And that's it. If I go back, should I click here? Refresh. This is the email field. This is the name field. And this is the password field. And when I click submit, the name is right here. So, we just updated just one place, which is a template. And it automatically set up the state for us. And it did all the things. It did the data collection for us as well. So, when you are submitting it, it gives you all the values right here so you don't have to hunt them around from your view component. I know this might sound like kind of a new thing. But it has been really around in the React world because they don't have a V model. They have to set up their own two-way binding. Yeah. So, this is makes it really straightforward in the React application. So, libraries that do this are something like Formic. Someone mentioned that in the chat right now. Formic is a really nice library. I think it is the most popular one. And it does the same thing. It has exactly almost the same API as this one, which is, I have to admit, it is the main inspiration for the next Vue-validated version for syntax. Because there is a lot of usefulness that comes from that world. In React, they don't have V model. So, they have to come up with another way, which is auto-tracking for your values. And I thought that would be useful for our Vue.js applications. Again, if I want to remove a field, all I have to do is just remove it like this and that's it. Now, let's talk about, so, yeah, if I try to reload right now. Yeah. The field got removed. Nothing really. So, it makes it really easy to maintain your forms as well. It makes it really easy to build a dynamic form, which we can take a look at, too. Okay. I will check some questions here. So, can the field component be used with other libraries? Yes, you can use it with other libraries. And this is, here is an example. So, you have this. We'll add another field. And we want to render a select component, right? A select field, sorry. A native HTML select. So, how can we do this? Because it seems like it shouldn't work with field. But all you have to do is, for example, let's add here, for example, ring. And we will use this full syntax. Then we will tell the field component which thing to render. So, you will render a select element that has a few options. So, copy, T, and auto, for example. And, again, it's not being validated at the moment. But render a select element with the options that we need. So, you can apply the same thing to your custom components, given they are registered globally. So, if you are using Vuetify or other libraries, you can actually use them. So, for Vuetify, it will be something like VTextField or VText, I can't remember, really. Or VInput. If you're using Quasar, it will be QInput. And, yeah, the tool works the same. You just have to be mindful of each component's API. And it not all of them will work just like that. Some will work just like that. Some won't. Some will require some advanced changes. So, let's talk about this a little bit more. So, right here, we have an email, the same email field I have replicated here again. But let's say we just want to get rid of this error message component. And we want to have our own styling, right? Because this is just rendering the native input, right? It's not giving us a lot of flexibility here. For example, if you are using Bootstrap or Tailwind, maybe you want to add some classes, maybe you want to add some elements, some indicators. So, we can do, we can render the same thing using the extended syntax. So, the extended syntax is really similar to the VValid version 3.

7. Using Scoop Slots and Field Object

Short description:

Scoop slots allow you to grab API from a component and bring it into your own template. The field object, available through the V slot, sets up V validate to validate the field. The compatibility between this approach and UI libraries depends on the component conforming to the API. V-validated documentation covers integration with popular UI libraries. Currently, Vuetify integration is not well-documented. Suggestions for improvements and additions to the documentation are welcome.

You have to use scoops slots. So, scoops slots are like a way to grab some API from a component, from a higher-level component, and bring it into your own template, which will be written here in the slot between the field tags. So, let's say we have our own custom input field. Just assume this is custom for now. It will be of type email, and this is no longer needed. And yeah, that's it. Let's also add like, maybe I want to render a div with a p tag for the error message.

So, how can we do this? So, the V slot gives you access to a few things. It gives you access to the error message. So, you can actually put it down there. We no longer need this. And you can grab something called the field object. Now, here is the main difference between the version 3 and version 4. While both of them may work the same in a lot of cases, you might not have to do a lot of changes. But instead of having the model on the node that you want to validate, you will have to use V bind and use that field object. So, what does this exactly do? So, the field object contains a few things that I will show you in a minute. But basically, at a high level, all it does, it sets up V validate to validate this field. So, it's a very simple thing to validate this field. And it is different. Right now, V validate isn't trying to auto detect it, right? You are telling it which input to validate or which node to validate, which is much more easier to maintain. So, if you are using VTify with a very complex markup like the data picker, you can grab this field object and throw it on the exact input that you want to validate. It shouldn't confuse it with the menu, for example. So, let's check if this is even working. So, it should still work pretty much the same. Notice that it has some empty space here, which is because of the paragraph element that we just added. If I click, yeah, this is the same thing, but it looks slightly different. So, you can pretty much have your own markup here and you can do pretty much whatever you want. Yeah. So, what does the field object exactly contain? Again, you don't have to worry about it, because it depends on the component type. But let's just look it up for fun here. So, notice that it has a few things here. It has the field name. So, you don't have to actually give the field a name. It has onPlayer, which is an array of functions. It has onInput, which is an array of functions. They are displayed as null here, but I think this is just a view of bugs. They are actual functions. So, what it actually does, it just adds some listeners, right? And that's it. It adds some listeners and it handles everything else for you. So, the compatibility between this approach and between the elements and the field component, like if you are using Vuetify or Quasar or whatever, boils down to this. If the component conforms to this API, if it emits a change event, input event, blur event, or model value event, then it will work. Otherwise, it may not work. So, we actually have, like, if you check the V-validated documentation, we have an integration page, which covers basically the most important validation libraries that you will probably use. Not validation libraries, sorry, the UI libraries that you will likely use, like Quasar, ElementPlus, Headless UI, which is a tailwind library, Ionic framework, and you can request whatever library that you like to use, and we'll consider adding it here to the docs. Vuetify doesn't exist yet because it's not really well documented how the input components work. Once it does, we will be sure to add it here.

I imagine you are talking about something like this, like you have the model of the form itself, and it will give you access to the data this way. At the moment, it doesn't work, but I think we can add this as a suggestion. So, let me note it down. Okay. You were talking about the previous example.

8. Accessing Form Values and Global Validators

Short description:

You can access form values in the template using the form component's scoop slot. The composition API solves the issue of accessing form values outside the template. You can apply initial values to the form using the initial values property. Changes in the form can be detected, but not the specific changes in each field. Props can be passed directly to the field component, but reactivity may vary. Global validators in V4 require the installation of the addVValidate/rules companion library. Define the rules globally in the entry point of your application using define rule. This makes the rules available throughout the application.

Like, you can't access the form values in here, other than the submit function, but you can access it in the template because the form element as well, the form component, does have a scoop slot, and that scoop slot does have a few things, like the form value. So, if you are interested in doing some conditions on your form values, so I'm just going to show you the form values. Doing some conditions on your form values. So, I'm just logging them here, and let me remove this field because it is confusing. Yeah, so notice this empty object here as I type it. Yeah, you have access to the values, but inside the form tag itself, you don't have it outside of here. You don't have it in the script, other than the submit function. Having said that, the composition API does solve this. So, if you are interested, wait till we get to it, I guess. Third question, not sure if this is... Yeah, I'm not sure about... I'm sorry if I pronounced your name wrong, Oldimer. I'm not sure what you mean here, but if you mean that you want to have some initial values, and you want to apply them to the form through an API, then you can do that. So, I'm just going to show you the I'm not sure what you mean here, but if you mean that you want to have some initial values, and you want to apply them to the form through an API, you can do that with something like initial values, which is a property on the form component itself. So, let's say we just want to add some initial values. It can be reactive, it can be static. So, something like form data, which you'll probably get from an API. Notice that I'm using the setup script, which can be a little bit confusing, but it makes the examples a lot shorter. So, let's just add a default value for the email, like hello at this com, and we'll just use it up here. If I reload, that's your initial values, basically. You can have a password as well, but I doubt it. But yeah, that's how you apply initial values, and it will validate it for you. So, if you make it invalid, it will validate it. Not sure if this is what you meant or not. Something else you might have meant is, can you detect the changes of the form? You can detect if the form changed or not, but you cannot detect what exactly changed. You'll have to go through each field and check it yourself, at least for now. But this sounds like a good suggestion. Can I pass props directly to field? Which kind of properties are you talking about? Yeah. Also, can we assign a ref to form and access the data? No, you cannot. Again, if you want to do that, use a composition API. Otherwise, you're stuck with this, which could be something that definitely could change in the future. So, I'm also taking suggestions from you guys. So, if you think something isn't exactly handy, then yeah, we can also work it out together. So, yeah. I imagine you are talking about something like this, like you have the model of the form itself, and it will give you access to the data this way. At the moment, it doesn't work, but I think we can add this as a suggestion. So, let me note it down. Okay. You were talking about the previous example. Yeah, any type of properties that you will pass to the field will be passed to whatever it is rendered by the field. So, let's say, again, let's go back to the select example. If you pass multiple, it will be passed around to the select element. So, you can give it whatever properties the actual component accepts. For example, if it's a VTify component, VText or VText field, and you could basically give it whatever configuration properties that VTify accepts. It works the same. But note, they might not work reactively. This is because attributes are not considered reactive in V3. So, if you have something that changes dynamically, it may not work. But for the most kind of properties, it should work. So, some properties will work, some won't. I haven't tested this thoroughly, so I can't really be sure about this. Yeah, let me check my notes. Okay. Okay. All right. So, let's try to clean this up a little bit. We have this. Let's bring back the error message for this component. So, you previously have used rules like, Larvel-like rules, like required by email, right? So, that still exists in V4, right? But it exists in a different way. You have to do a little bit more things to get it to work, because they had a significant bundle size, and many front-end users may actually not want to use this kind of syntax, because it has some downsides. So, let's clean this up. Let me comment this out for now, and we can talk about advantages and disadvantages. So, how can we make this to work exactly like it used to? Like, how can we get it to work like this? So, required email, and this would be required in three or six. So, yeah, we just want to have the same syntax, which is nice. It's really nice. You don't have to declare some weird functions down there, and you don't have to bind them. It's really handy, but let's see how we can set this up. So, let's go back to our server. So, these kind of rules, so these string rules are called global validators, right? So, global validators actually require you to install another VValidate library, a companion library, if you will, and it's called addVValidate slash rules, and it's added. Run our server again. Don't want to forget it. And so, how does it work now? Obviously, there's a kind of setup that you have to do. So, a good place to do this is in the entry point of your application. So, in main.JavaScript or main.js in this case, doesn't really matter. So, you need to do two things. You need to define these rules globally. So, like, they are named global rules, you have to globally define them. So, from VValidate, so this is a core library, you will get something called define rule, and from VValidate slash rules, you will get whatever you want. So, you want the required rule, and you want the AMA rule, and you want the minimum rule, right? So, you need to define the rule, and you want the minimum rule, right? So, very similar to the previous API, but this was named differently. I can't even remember what it was named. So, yeah, it works like this. You have to call the define rule with each rule that you're going to use. You can clean this up more, but yeah, it works most of the time for you. You usually would have your own validated JavaScript file, or the TypeScript file, and you will import the file, the stuff there. So, as a best practice, you usually have similar to ViewRouter, like, it's own file, and you will move all this stuff there to avoid polluting your main file, and you will do something like this. You must use the relative path to make sure you are not importing the actual library. Yeah, so let's check it again. So, this defines the rules globally in our entire application, so they are available everywhere, right? This makes it really easier to use them, and also gives us, like, a few downsides to it, but let's get it to work first, and then we can talk about the downsides. We no longer need this, so let me commit it out, and this, as we currently have it, should work, but as you know, with those live demos, it can, let me remove the initial values. Never, nothing ever really works from first try, so let's see.

9. VValidate Messages and Global Rules

Short description:

If I try to click submit, it says email is not valid, password is not valid. We don't have rules or messages for these rules. To get our messages to work, we need to install another library called vvalidate/internationalization. This library contains error messages for different languages. We import the language we want, configure vvalidate to use the localization engine, and give it a message generator. There are three ways to validate: plain JavaScript functions, global validators, and a recommended third way that combines the best of both. Use functions for flexibility and global validators for bundle size optimization. Measure the impact on your application and optimize accordingly.

If I try to click submit, it says email is not valid, password is not valid. Okay, yeah, we know that they are not valid, but we are not really getting why they are not valid, right? So, it's not telling us a lot of information. This is because we don't have a, we don't have rules, we don't have, sorry, messages for these rules, so each rule must have its own message, and we didn't do that.

So, we also need to set up a different thing here to get our messages to work, so it can, it can be as easy as you have to, let me see if this still works. No, okay, so in order to get this to work, you need to install another library, okay? You need to install another companion library called at vvalidate slash internationalization, so let me close the server, so it is named like this. It contains all the error messages for you that existed in vvalidate before this release for all the languages that you guys have submitted. A lot of users all around the world submitted their own languages, and I'm very thankful for this. So, you have access to a lot of languages here.

Now, let's import the language that we want, which is, which would be, first, let's import a couple of things. There is a different API here, a little bit. Let's import the language first, so as you can see, we have a whole lot of languages, so we'll import the English one, and this should be the messages, right? Should be the messages object, and right here, we need to import the configurator for it, so there is a function called localize, right? Now, with vvalidate, you need to configure it to use this localization engine. I know things are starting to get a little bit more complicated, but this is the cost of using this method of validating. It requires a little bit of setup, but once you have set everything up, it just works for you. So, we need to give it a message generator using the configure method of the core vvalidate library, and the generate message should be a function. Localize can do it for you, so you just give it something like this. You say, are we going to use the English localization, and here it is, and here is the messages for them. Let's see if this works or not. Again, I haven't used this in a very long time, so I'm not sure if it's even going to work or not. So, yeah, it worked, right? My email field is required, so because it filled the required rule, once I start typing some things, maybe it should fill the email right now. So, yeah, it must be a valid email. Same thing for the password. Once I start typing characters, list, and six, must be at least six characters. So, that's it. You're done. Once you have set this whole thing up, it's straightforward from here on out. You don't have to define anything, really.

So, if we need these rules in a different way, so, for example, this is another read that maybe it is not required, you can do this. Okay, this is the, I call them the Laravel rules because they are heavily inspired by Laravel, right? The famous backend PHP backend framework. And this is actually what VValidate started with. It started with these rules all built in and started using the syntax since version two and it carried on to version three. But in version four, that kind of got de-prioritized. And the reason for this, because from, like, again, as a frontend developer, we have a lot of backgrounds, right? We come from a lot of different backgrounds. Myself, I was a backend engineer. I was Laravel and Node.js, then a little bit of Rails. Then, meanwhile, I was studying frontend a little bit. So, I moved on to the frontend world. So, my background is very backend heavy. And some concepts doesn't really translate well into frontend and backend, right? Because there are different concerns. For example, in order for these rules to work like this, you need to define them all globally, right? You can have a different, slightly different approach here, which is maybe in this component, you just want the required rule. So, you can copy this, copy this. And in here, you can do something like this inside this own component. So, and you can configure this rule just for this component. You can do that. But again, this is kind of the purpose of having them as global rules. They are supposed to function globally. They are defined ones, and then you can call upon them whenever you need them.

The problem with this approach is, from a backend perspective, calling upon validation rules is cheap. Everything is already loaded into memory. You don't have to, you don't have to like an overhead of adding another validation rule. You don't have really a lot of concerns here. But in the frontend, there are concerns, there are consequences, because the more rules you use, so we have around, let me check the documentation for you. And they are listed under global validators. So, let's check available rules. You have here, like, right around 20-something rules. So, all of these rules have a bundle size, right? The more you add to your application, the more they will make your app heavier. They will make your app take a little bit more to download. And because of this, it will take a little bit more time for it to be interactive. So, they are not great. They are not the best way you can build form validation in the frontend world. So, VValidate kind of had to respect this. So, that's why it became a different library. And you can integrate it with the core VValidate, if you want. Because most of the time, people like to roll their own validation rules. And in a lot of cases, we have to agree on this, that most frontend developers don't have a backend, may not have a backend background. So, they may not actually appreciate this, actually dislike this whole global rules thing. And it gave VValidate initially a really bad reputation of it being much larger than the Vue.js framework itself, which was kind of embarrassing. But it was the cost of easier development, I guess, for everyone. So, VValidate tries to say stay in the middle here. Doesn't try to overzealous with what it can give you. And same time, it is almost minimal. So, it doesn't really make your app a lot heavier or slower. So, we have seen right now two ways you can validate everything. There is a third way, which is actually going to be the recommended way going forward, because it kind of has the best of both worlds. Like, it brings really nice way that you can do all of these things. So, let's recap the two validation methods that we had. So, first, we had just plain JavaScript functions that you can use with third-party libraries. This is the most basic one. And at the same time, it is the most flexible one, because it's a JavaScript function. So, you can do pretty much whatever that you want, right? Nothing will ever stop you. You have access to everything here. So, you can do pretty much everything. But then we have another way, which is global validators. You define them once, and you use them all over. So, what are the disadvantages and advantages here? So, I would say use functions like these if you are worried about your bundle size and you are trying to optimize your app as much as possible. And using the global rules will really help your application. Again, the rule here is that you should measure, check if it really slows you down. And if it is, then you should optimize. Don't assume anything out of the get-go. But the global rules, when should you use them? Well, you would think that with them slowing down your application, you would think maybe never. But there are actually a lot of use cases for them.

10. Using YEP for Validation

Short description:

When building admin dashboards with multiple forms, it makes sense to use validation rules that can be reused across the application. VValidate provides a third way of validation using the YEP library, which allows for the creation of validation schemas. These schemas define the rules for each field, such as email validation and minimum password length. The YEP library offers a middle ground between global validators and custom JavaScript functions, providing efficiency and flexibility. Additionally, YEP introduces form schemas, allowing for the validation of fields based on other field values.

For example, if you are building an admin dashboard, and I'm sure a lot of you did, how many forms do you have in admin dashboard? It almost never ends, right? Every single model that you add, you will have to add a form for it, you will have to add rules for it, and the rules repeat across the board. So, here it is required email minimum or whatever. Yeah, they repeat a lot. So, these rules actually make sense to use in these use cases. When you have a lot of forms, they just keep repeating. Maybe a dynamic form, maybe you have a form wizard that the user uses to get a certain service. So, like type form, for example, if you are familiar with that product, you have like this wizard thing. So, rules are going to be repeated a lot in the application. And they are not localized to a single component, right? They are all over the app, and they repeat frequently, and almost they are redundant, they are duplicated. So, actually, the overhead of importing the validation rules here is actually much better than having to define each validation function on its own in every single component. So, this becomes, the cost here reduces to almost nothing. So, it's safe to use it then. So, now I have talked about these two approaches. I'm going to use either. There is a third way. The third way is using something, another library called YEP. So, yeah, it's just a three-letter library called YEP. Run the server. So, let's go back to what we had here. Let's remove all of this, and let's use YEP here. So, YEP allows us to build validation schemas. It has a slightly different way to do so. So, they call it schema. So, let's import first everything from YEP. So, we can do this. Okay, and let's create the rules. So, let me remove these. Make sure we are not confused by them, and I forgot. Right. Okay. So, let's create first a schema for the email field. So, it is simple as, for example, it's called email. It will be like yep.string. So, it is a string. It always starts with the type of the value. So, you have string, you have number, you have object, you have Boolean. I'm not sure what else you have, but you have a lot. You have mixed for stuff that are complicated or that their values type may change. It may be a string or maybe a number. So, for now, it's just a string in our case, and it is an email. So, just dot email, and it is required. Just required. Let's repeat the same thing for the password, and let's call the password schema. So, string, it's not an email, but it has a minimum length of characters. So, it should be, for example, five or six or whatever. So, yeah, it is very similar to the global rules, right, because you have access to almost all the different, like, combination of stuff that you can do on a string, but it is also in JavaScript. So, you can have a lot of control here over what you can do or not, and VValidate actually takes this a little bit further. So, let's just see if they work or not. Yeah, sorry. Let me close this tab. So, once I click submit, it says this is a required field. Notice the messages change slightly from each way, which method or which way we validate our fields. This is because each have their own messages. So, once I type something here, it is no longer required, but it should be a valid email, and once I complete it, it is valid. Same thing here. If I remove a few characters, yep, and that's it. Now, one thing special about YEP, so this is the way I would recommend that you always use in your application, because they are both efficient and you can pretty much call upon them whenever you need them. So, but first, let's optimize them. So, we are importing everything from YEP, and we don't want that. So, let's import only the parts we need. So, let's import only the parts we need. So, we only need the string validator here, or the string schema. So, that's it. Now, we just imported the string, your bundle size is happy, and you've got the validations that you wanted. It's a good middle ground between the global validators and the custom JavaScript functions. What's really nice about YEP as well is it gives you like the best of both worlds. Like, you can have your own test function, like custom test. Let's say fail custom test. And you can add your own validation function. So, so, so, YEP can be extended. So, it says, and it works similar to other ways. So, yeah, but it didn't run the custom test one. I may be, I may, might have done something wrong here, but yeah. Maybe does it need to be refreshed? Yeah, I have done something definitely wrong here. I'm not sure about it. But take my word for it for now. You can extend the rules with your own stuff. Is there a better way to compare to buzzwords? Yes, we are getting to that, actually. So, one really cool thing about YEP is form schemas. So, this was never available before with VValidate, but now it is. So, instead of just, let's say you added another field right here, and it is actually the confirmed buzzword that you asked about. And I like to use camel case. It is a buzzword, and we basically want this field to match this field, right? So, this can be hard to do without really getting the access to the other value using the two other approaches. If you are using custom validators, it will be hard to get the values themselves and validate it yourself. But if you are using the global validators, you can actually grab the, let's say, from the rules here, you have a rule called confirmed. So, you can grab it, register it, and you have to say confirmed at buzzword. So, confirmed by the buzzword tree. You can do this, but again, this is the old way of doing things. Really, here is where the app really shines. So, for now, let's take a step back and talk about form schemas.

11. Defining Validation Schema and Form Actions

Short description:

VValidate allows you to define the entire validation schema for a form at once, eliminating the need to declare rules for each field individually. By passing the schema to the form component, you can easily add fields and their rules in one place. The validation schema approach is recommended for fixed forms that don't change frequently. It simplifies maintenance and saves time. However, if you have dynamic fields or complex rules, other options are available. You can reference other field values using the ref method from IAPT, which allows for relationships between fields. This integration with IAPT is inspired by Formic and provides efficiency and flexibility. Form actions, such as resetting the form after submission, can be performed within the submit function using the actions argument provided by V-Validate.

So, right now, I have to add this field again, right? You have to add this schema for the buzzword confirmation, and you have to pass it, put it up there here, which can be tedious, right? You are, again, there is friction here. VValidate removed the vmodel friction, but now there is a friction and adding the rules themselves. You are going back between the template and the JavaScript just to add a few things.

So, VValidate does something really interesting, which you can use object schemas. So, let's say we have the entire schema for the form. So, you can define the whole thing at one go. So, something like this. Then you can list your fields. We have an email, which is a string. It is required, and yeah, I forgot that it is an email. Let's repeat that for the buzzword. This is a string. It should have a minimum of six, and it is required. Let's add the buzzword confirmation, and it is a string. You can add a minimum rule here or not. It doesn't really matter, but it is required because it always has to match the buzzword, right? We'll see how to do this in just a minute, but for now, let's just ignore this field and remove these. We no longer need them, and you no longer have to declare any rules on each field. You can completely eliminate this, and pass the entire thing to your form, so to the form component. So, it's a validation schema, and we give it the entire schema, and that's it. You no longer have to worry about what each field needs to have, and this makes it really easy. Now, you just add whatever fields that you want, and just go down there and add them, add the rules for them in just one place.

So, let me remove this and see if it still works as it is. I should also remove this. I click submit. It says email is a required field. Buzzword is a required field. Once I start typing some stuff, and it still works the same thing in the exact same way, but this is actually a lot nicer, and as a creator, I really recommend you that by default, go this way. Always define a validation schema on your forum, and don't worry about the other fields. It will save you a lot of time, and it can really scale really well, but the other options are available for you. If you are having difficulty with dynamic fields, for example, maybe you have fields that may exist or not, so you'll have some difficulty defining a single schema for them, right? So, yeah, maybe use this if you have like a fixed form that doesn't change, although there are ways to do this for the schemas, but yeah, by default, this works for, I think, 80% of your cases, and you still have the other ways if you need more.

So, let's add this field called confirm buzzword, right? It should have the same name as the error message, and we should add it here. So, it is a string, and it is required, and since it should always match the buzzword field, we don't really have to say it has to be a minimum of six. That's just repetition, but we haven't really tied them together, so how can we do this? Well, IAPT has a really nice way of referencing other field values, so you can do something like you grab something called ref from IAPT, which is not to be confused with ref, which is from Vue.js, so both Vue.js and IAPT have the same method here. Be careful not to confuse the two, because that will happen, and then you can say this buzzword field can only be one of, and you give it a list of matching values, and we can give it an array, and that array will have a single value, which is a ref of the other field, which is the name of the other field, which is the buzzword. This is the IAPT's way of doing this. It can be a little bit confusing, but it works really well, so then you can add an error message, right, because it will just say the value doesn't exist in the list, which is not really helpful, like what kind of list are we talking about here? So, the message here is the field doesn't, does not match the buzzword, or the confirmation, to be more exact. Yeah, the confirmation does not match the buzzword. So, this should set it up for us, so let's try this again. I'll click submit. Of course, nothing really submits. It's angry about everything, so let's fix that. Let me write something predictable here. Okay, so once I type something different, it says it doesn't match it, but once I match it exactly, it just goes away, and we can submit, and that's it. You can reference other fields for other purposes using this way. You can actually have, for example, for some reason, you would have an age field, maybe, and you can actually say it is a number. Sorry, you have to import it from IAPT. Again, with IAPT, you import what you need. This is the best practice of doing it, which should keep your bundle size as small as possible, because, yep, it's kind of large, but even if you use the whole thing, it shouldn't really, it should have also like a small impact on your bundle size, but yeah, you should always keep it to a minimum, like use only what you actually want to use. So, there's, I think, greater than in there. Yeah, they have more than, and you can reference another field. Like, it has to be, like you can make it 18, for example, or you can reference another field, like other fields. So, this RIF thing is really useful if you want to have this relationship of validation between your fields, and it's really straightforward. You can, it's really easy to read. For example, I'm just, I'm a developer. I'm like your teammate, and I just got into this project, and I have this form that I need to add a rule to it. So, what I will see down here, I will notice you are using something called a validation schema, so I will go to that, and I can see, yeah, email is a string email required, and if I needed to change that, I can just remove the required part if I want to. It's really easy to maintain, is what I'm trying to get at. So, yeah, this is why IAPT is really encouraged for you to be used. It's own validation library, but the integration between it and VValidate really makes a lot of sense, and this actually one of the, I would say, lessons or things that got, that VValidate took from Formic, for example, which is their library, because Formic actually uses YAB a lot, and in their official examples, so it made a lot of sense to just do the same, because YAB is a very mature library, has a lot of users, very well maintained, has TypeScript support, there isn't really a point of having our own rules just to have like a single solution. So, the best way here is to impress multiple ones. Sorry, there is a question. Yes, this is actually documented. You can find it in the documentation, in the validation guide. It doesn't, of course, again, VValidate doesn't delve into the details of the YAB library. If you want to learn more about it, go to their own documentation and learn more there, like localization. VValidate doesn't handle localization if you are using YAB, so you may have to do this on your own using YAB itself. So, check their documentation out, and yeah, I'm using this in production, and it's really, really handy, and we have really complex fields with really complex rules, and yeah, it works really well. Okay, let me check my notes. Okay, we are handling the submission right now. Typically, you get these values, right? You get the values, and you submit them to your server. I'm just alerting them here on the window, because I don't have a server set up right here. Maybe I should have, but yeah, I don't. Now, let's talk about something called form actions. So, what if after we submitted the field, we want to reset everything? This is a very common use case, right? The user submitted, and then the electronically detected the that's how I guess online talks slash workshops work over zoom. But yeah, honest mistake. Anyways. Yeah. Let me just gather my thoughts. Yeah. So for matches, yes, you are going to like, it's very common that once you took the data from the user, that you are not, you're going to reset the entire thing, right? It doesn't make sense in a signup form because usually take them to, their dashboard and that's it, right? You take them to their dashboard or to their page, or you tell them, Hey, your account was created, show them a different screen. And that's it. But again, this can be applied to this example as well. So let's say after the user submits this form, we want to reset the entire thing. No, we can do this in the submit function itself. You can actually do this right here. And it is actually the most like the most place that makes sense because where else are going to reset, right? You're mostly going 80% of the time you're going to reset after submission. So there is a second argument that V-Validate gives you. It's called actions and these are called form actions. So you can do various actions on your form. One of them is to reset the form itself.

12. Handling Form Submission and Invalid Submissions

Short description:

Let's explore the available methods for handling form submission. The resetForm method clears all form fields. Another way to access the form instance is by using template refs or the options API. However, caution should be taken when using template refs with V-Validate. It is not recommended to use the same approach as in version 3. To ensure email uniqueness, you can communicate with the backend after form submission and use the setFieldError method to display an error message. Additionally, there are other methods like setFieldTouched for handling invalid submissions.

Yeah. But first let's, let's check out what's available here. Maybe you want to see what can we do in general, then decide what we really want to do here. So let's log it out. Let me open the console dev tools. Hopefully you can see it clearly. Now I have to go through the hassle of correctly filling the form. Yeah. Okay. So now it alerts, the alert blocks the execution. So I'm not seeing anything down there, but then once we click, okay, we see a few methods that can become really useful for our use case.

So we have the event itself. This is the event, the submission event of the form, the native event object. It may not always be available because you may have used a different component for submission, which is something I forgot to mention, but let's move on. You have other things like reset form, set errors, set field error, set field touch, set field value, set touch, set values. There is a lot of things to unpack here, but let's go to them not necessarily one by one, but the main ones. So let's call the reset form, which should clear everything for us. So actions.resetform. Again, you need to type everything correctly. And once I click submit, again, notice nothing really resets because the alert blocks the execution of JavaScript. But once I click okay here, everything clears. So that's reset form. It's really handy. You can do it like this. There is another way to do it. If you really are interested in grabbing the form instance, the component itself, you can do this. So you grab a ref and call it form, for example. You can get a view ref. And now you can see the conflict between yep and view, right? So let's change this name to make it less confusing. So this is the view ref. We'll use it to grab the form. And start with null. And then you can call form.value.resetform. So same thing, but here you grabbed it using template refs. And if you are using the options API, again, I'm using the setup script, which forces us to use it like this. But if you are using the options API, you will access it with this.refs.form directly. You don't have to do this whole dance that I just did. So I'm sorry I'm not delving into the different mechanisms of each of the options API versus the composition API, because, again, it's really hard to cover both at the same time equally. So I'm just mentioning tips here and there on that. So you can still do this, but it's not really recommended because if you are using TypeScript, you really have no way to tell what's going on here. So let me bring back the ref. So you can't really ensure that this form will contain the form actions, right? Because it can be null. Maybe the component hasn't been mounted yet. So if you do something like this, repeat this. If you do something like this, it will actually crash the app because it didn't exist yet. So this is a little bit dangerous. So, yeah, limit your usage of template refs with this version of V-Validate. Don't try to do the same things that you used to do in version 3 with the validation observer and the validation provider. Again, the composition API does solve this issue if you're having access to everything. But for now, let's just move on and we'll get there. Let me remove this.

Okay, so we have reset. But let's say you're submitting this to an API, right? A backend. For example, you're submitting the email field to the backend. And it turned out there are some user has already registered using the same email. So uniqueness, email uniqueness. It is very hard to do it on the frontend without communicating with the backend. And there are multiple ways to do it. You can create a custom rule of JavaScript asynchronous function that asks the backend about the uniqueness of that email. Yeah, I will answer the question in a few minutes. Sorry. So yeah, the uniqueness. You always have to communicate with the server to be able to ensure uniqueness. But you can do it after the submission, right? That's very reasonable to do. You can actually let the user submit. And if it turned out to be already taken, we just let them know. So how can we do this? Let's imagine this, like this is an API call. Since we don't have a server, we just have to use our imagination for now. And right now, let's say it turned out to be like the email was already taken. So in the actions, you saw that there was other stuff that were useful, like set field error. So we can say that this email field should actually have, should be like we let the user know this was already taken. So this email was already taken. And just be sure not to reset it. Because if you reset after sitting there, it will reset it. So make sure to do it before or after, or depends on your use case, really. So let's type some, an email here. Click submit. Yes, everything is here. But yeah, this email was already taken, shows up. So you can do this. It's really nice that you can set errors after the submission or after the fact. Now, what else can we do after submission? Or we have a lot of things. Like I mentioned, you have something called set field touched. I will get more to that with the composition API, because it doesn't make a lot of sense with the validation components. You can't actually make use of them as much as you would like to. But yeah, let's talk about something else. So handling invalid submissions. So let's say the user tried to submit the form and it turned out to be invalid. Like the form, yeah, turned out to be invalid. Can we do something about it other than just showing errors? So let me remove all of this.

13. Handling Form Submission and Invalid Fields

Short description:

If a form spans the screen and requires scrolling, it's important to consider the user experience. There are multiple ways to handle this, such as showing a popup or scrolling to the first invalid field. By using the onInvalidSubmit function and the context object, we can access the errors, results, and form values. To scroll to the first failing element, we can grab the field name from the errors object and locate the corresponding HTML element using JavaScript's querySelector. Then, we can use the scrollIntoView method to smoothly scroll to the field. This provides a better user experience and helps users identify and correct invalid form fields.

If I click reload, so they click submit and yeah, all the errors show. But what if it is slightly, like there is a slight difference here. So let me do something interesting. I'll add a CS class called field. And let's add some styles. Again, we are not going to focus a lot on styles. This is just for demonstration purposes. Let's give it the height of 500 pixels. Yeah. Let's click submit. Now you see the issue, right? So the user can see this field, but they can't really tell if there is another field out of the viewport that they cannot handle, right? Or they can correct. So maybe they will, they can't see this immediately. So they will try to fix this. This doesn't match the password. They will go up to the password and type something predictable again. Yes, they click submit. And it doesn't submit and they have no idea what's going wrong. They don't know that this field is invalid. So what can we do about this? So this is more of a user experience thing. This is something that maybe you should do as a developer. If your form really spans the screen like this, like the user has to scroll to view everything. So you should keep this into account. So how can we handle this? Well, there are multiple ways you can do this. Maybe you can show them like a popup that tells them, hey, you forgot the field up there that's invalid. Or the following fields are invalid and they will notice that the other email field isn't there. So they will scroll up. Or you can scroll for them, which will be nice, right? So let's say we have another function called on invalid submit. And pvalid offers you this event on the form object. So at invalid submit, we'll call this function. And for now, it's just an object called context. So let's look at the context and see what we can use with it. Again, I reload. I click submit. And yeah, there it shows. But we notice that our invalid submission did run. So it contains something called errors. The event submission event again. A more detailed results object. And the values of the form when the user submitted them. So if I type something here, click submit again. Now we have a new object and it tells you the values. So it gives you a lot of information about what exactly went wrong and what was the form state when it went wrong. So in order to scroll through the field, we need to do a little bit of a dance here. So we need to grab the field name. So going back to the object, how can we do this? We will notice that we have the errors object, which is a dictionary or a map between the field name and the error message. So we can actually use this. And let's grab the field, first field. So field. And, sorry, excuse me. And we have, we grab the errors object and we grab the first key, which is the first failing field. Right? Now, it should have a field. If it doesn't, then there is probably something wrong with your form. Maybe you added a rule for a field that doesn't exist. So you should be careful about this. So let's locate this field. So how can we locate the HTML elements of this form? Let's inspect it, see if we can use something here. So you'll notice that we can use the name of the field as a selector. Right? This is just JavaScript API. You can just use the same, you can use the same JavaScript API that you are already familiar with. So field element equals document.querySelector. And for the selector, we have to just craft it dynamically. So we want to grab the input, which has a name equal to the field. And this should give us the input element itself. If there isn't a field element, maybe we shouldn't do anything. But we have a nice syntax for JavaScript for this. So field element, if it exists, do something. Otherwise, don't do anything. This is the conditional chaining. So if it's null, it will be safe. It won't do anything. It's just a nice condition here. So let's say scroll into view. And we can specify the behavior to be smooth. This is, again, native API. It's not view. This is native JavaScript. And it should scroll to the first failing element each time. And the first being the first in the errors object. So it can be unpredictable. But it is better than nothing. Right? So if I click submit, it did, like, go here. You may actually want to do something different here. Maybe because this field will never be correct, unless this field is correct, maybe you should sort the field names. But, yeah, we won't overcomplicate this because we are short on time. So 1, 2, 3, 4, 5. So both are valid. Let's try submit again. It fails, but it scrolls you to the first failing element again. So we can see what's going wrong here. And they can correct it.

14. Using the Composition API for Form Validation

Short description:

Let's repeat the form using the composition API. Instead of form, field, and error message components, use use field and use form. The composition API offers the same API as the components, but with access to everything. The difference between the form component and the composition API is that the composition API is decoupled from the UI. Use the submit event when you want to submit the form. VValidate is built using the composition API as a first class. The form component is actually calling use form. You can mix and match components created with use field and the form component. For consistency's sake, let's remove the components and only use the composition API in a pure way. Make sure you call use form first.

Sorry. They can correct it. And go back down there. Click submit. They submit it, and everybody is happy. So, yeah, this is handling invalid submissions.

So we are done with this is the primer of, I guess, revalidated features. But let's talk about the very important thing, the composition API, which is a little bit, can be, like, intimidating at first, but it is very easy to use. So let's repeat this whole form again using the composition API.

I need to answer questions. Sorry. Is there an easy way to debug when the validation is not working? Yes, we will come to that in the section after this. So we have this. Then we will talk about field arrays. Then we will talk about the diff tools. So this is actually part of the diff tools. Okay. So let's repeat this whole form using the composition API. So instead of form, field, and error message component, you will use something called use field and use form. So same thing, but they have the word use in front of them. And the way it works, it offers you the same exact API as the form and field components, but they give you access to everything. So unlike the form and field components.

So let's create the first form. So you always have to start with the form. Keep this in mind. Let's keep the schema up here. So we use the form and we can pass to it the validation schema. So schema. This is the same thing. That means we no longer actually need this at all. So we can entirely remove this. All right. Now this is the native form element. It's not the form component. But we still need to do a few things. So as a validation schema, and that was almost all the attributes, right, except for the submit event. Now the composition API, it takes a little bit of like changes and able to make it work exactly the same as the components API. It can be hard, but also very easy. It depends also on the use case. So we grab something called handle submit. And this is the submission handler function. So all you have to do is create a submit function for that form. All you have to do is create it using handle submit. So handle submit takes the callback, this exact signature. And that's it. This is the submission function that you should use. So you can grab it and use it on your native form element. So on submit equals on submit. And you don't have to use prevent. It will be done for you. You may ask why should I use this? It sounds like a long way to do the same thing. Or it's not really the easiest way to do it. But you may not always can use a form component, a form element, right? Maybe this is a div. And divs obviously don't have a submit event. So maybe you want to have it on click instead here. So you can do that. It's just the difference between the form component and the composition API is the composition API is decoupled from the UI. It doesn't care what you have as a UI as long as you use the things correctly. So submit event, use it when you want to submit the form. Here you call your API and you do whatever you do. And yeah. So let's bring it back to form to Basemantic. Or we can just leave it like this to make it a little bit different. So I don't recommend having fields not in a form element for accessibility purposes. But again, it's your use case. You are in control and VValidate just has to offer you the tools to do so. Let's make sure validation still works and submission actually still works. So if I click reload, notice that it fails because we no longer have the field component, right? I removed it. If I introduce it back again, yeah, it still works. I just want to show you something. Then we will migrate these components to the composition. So notice that I have no form component at all. Yet when I click submit, it still works the same way. This is because VValidate is built using the composition API as a first class. It uses it from the ground up. Even the field and form components are using this same composition API. The form component is actually calling use form. So you can have the exact same features and build really powerful components using the same APIs. And because both actually use the same composition API, you can mix and match between them. You can use use form as a composition API function with the field component. And you can use the form component with components created with use field. So you can mix and match here and they will just work in the exact same way. Because you can think of VValidate as this validation API, this general validation API, like an electricity. And you are only getting the outlets for it. You can hook into this outlet or you can hook into this other outlet. You can use higher order components or you can use the composition API or you can use both. It's really up to you. But for consistency's sake, let's remove these and only use the composition API in a really pure way. So make sure you call use form first. Because if you call use field before it, it won't actually know.

15. Creating the First Field

Short description:

Let's create our first field, which is email. We don't have to specify anything else. The use field function gives you access to the field value and the error message. We have replaced the usage of the field component and error message component.

So execution order is very important here. So let's create our first field, which is email. And we don't have to specify anything else. You can specify the rules if you are using the global rules like this. So it is very similar to a component. So you can do this. Or since we have a validation schema, you can completely ignore it. So the use field function gives you access to a few things. It gives you access to the field value and it gives you access to the error message. So now we have already replaced the usage of field component and error message component. So let's do that here.

16. Using VModel for Two-Way Binding

Short description:

We no longer have a field component, but instead, we'll use an input. To bind the input to the field created by VValidate, we can use VModel. This allows for two-way binding and real-time validation. However, there may be some issues with this approach.

So here, again, we no longer have a field component. So we'll just have an input and we no longer have an error message. So we'll have component. We'll have an error message variable. But, okay, how will VValidate know that this value belongs to this field? Now we have to use VModel again. So if you like the familiar VModel, you can go back to doing this. And I will show you how we can actually, this isn't the intended use case of the composition API, but you can use it like this. So VModel equals value. Now we have two-way bind the input to the field created by VValidate. And whenever this value changes, VValidate will validate it for you. So let's replace all the others. So I will have to repeat this. And you immediately start to see some issues here. Let me check the calendar real quickly to make sure I'm not running out of time. Yeah, we still have an hour, I think. Thanks for sticking around.

17. Using the Composition API for Form Validation

Short description:

We need to rename some variables to avoid conflicts. The composition API allows for real-time validation. You can disable validation on value updates. The handle submit function accepts two arguments. The first one is the submission handler, and the second one is for handling invalid submissions.

Okay, so, okay, we have a problem because the same names for the variables exist. We can't have three values, right? So we'll have to rename some things. So we'll rename this as email. We'll rename this as password. And we'll rename this as confirmation. Error message, same thing. So email error. And you start to see the issue here, right? This is extremely tedious. Password error. But let's just, this is the most, I would say, naive way to implement the composition API. And you probably will start with this in your first application. And there is no shame with this. It works. And if it's working nice for you, go for it. But it's not the intended use case. You shouldn't use it like this. So confirm error. And now we have to set up our things, right? We have to set up the email, email error. We have to basically repeat this three times. Remove this. This was the password, I think. We have to give it a type of password. Password error. Confirm error. What was it? Confirmation? Yeah, it was confirmation, I think. Yeah, it was confirmation. And the name here. The name really doesn't matter anymore. Again, the composition API no longer cares about what you have as a UI. It only cares about you hooking up the right things at the right time. So we have replaced the fields with this setup. And this needs also a type password. So let me reload. Right submit. I'm not sure if it's real, but there are issues here. Use field password confirmation. Yeah, the name is different than the schema. So I should stick to that. Yeah. If I click submit, yeah, everything works the same way. But notice that the validation is now real time. It's no longer triggering on change. This is because, again, the composition API doesn't really know when you should validate or when you should not. So it will just by default validate whenever the value changes. You can disable this behavior and start to bring it to be a little bit more similar to the field component. So we have no rules. So you can send null or you can send undefined. It doesn't really matter. And we can disable validation on value updates. So we disable it. If I reload and start typing here, it doesn't validate at all now. It only validates on submission, which is not what we want. We want to submit on change. So you can do multiple things here. You can disable it from here or you can still enable it and use lazy. But let's just do everything in V-validate terms. So you have another function called handle change. You can grab from the use field. And let's say on change we just want to handle change. And yeah, I think that's it. Click submit. Sorry. Let's try first result to submit. So this is the exact same behavior that you got in the field component. And this is actually what the field component does for you under the hood. It configures some reasonable defaults for you that it can assume safely. But the use field function cannot make the same assumptions. So it can't really have this behavior out of the box for you. You have to configure it. And yeah, so let's bring everything back to the composition. And see if we mirror the exact same behavior as before. Let's see if the form still submits and still alerts with the values. Yes, everything still works. However, we have one thing that we didn't mirror, which is invalid submissions. So how can we do this? Well, with the composition, it is slightly different. But you can have your function embedded as a second argument of handle submit. So handle submit actually accepts two functions. The first one is always required, which is the handler itself, the submission handler. This only executes when everything is valid and the user did submit the form. So if they tried to submit the form and there was something wrong, it won't execute. But the other one will execute. So it looks like this. It is slightly cumbersome, I think. But if you are using TypeScript, it really works well. And yeah, it's not really that bad. So it still works the same. So let's see if we can get the element. So let's go to the field element, scroll into view, behavior, smooth. And let's bring that height thingy. Okay, I think we are good to test this.

18. Using Callbacks for Form Submission

Short description:

The tradeoff of using the composition API versus higher order components is that it provides more flexibility but requires more manual work. Promises are not desired for handling form submission and validation errors, as they can hide actual bugs and confuse users. Instead, a callback-based approach is used in VValidate, which ensures that validation errors are not mistaken for other types of errors. This approach was introduced in version 4.5 and is recommended for handling form submission and validation.

So submit. So the element may not exist. Because the field component added the field names automatically for us to our inputs. But now we no longer have this thing for us. So we need to do this on our own now. So this is basically the tradeoff of using the composition API versus the higher order components. It's more manual, but you have more flexibility.

So flexibility at the cost of convenience, I guess. Let me make sure to get the exact name right. So let's try this again. I will click submit. Yeah, again, the order is not guaranteed. For this time, it got us to the first element. So the first input, which didn't do the previous thing with the previous component's usage. Which, again, it's not guaranteed.

Why not promise API? Right. So this is actually a really good question. So why not just have something like, for example, let's just remove this. And let's say you can have a catch, right? I think this is what you are aiming to do, right? Let's have a catch here that handles if something went wrong. The issue with this is it will actually hide your actual bugs. For example, if you have a throw right here, it will trigger the invalid submission function, which isn't quite right. It's not what you are. It masks user errors as validation errors, which is an issue. So here promises are actually not desired. And there isn't really a good way to make it less confusing. Like, I have tried emitting an error that has a specific type. But you have to check for that type. So instead, I opted for just do this. It's a callback-based. Yes, it's old school. But I think it works nicely here. And it won't confuse you. This is the most important aspect. If you are having an ABI that won't get in your way and confuse you to, like, you will get this error that maybe actually you're a good error. Maybe your submission to the ABI failed, a network failure. Then it will be treated as a validation error, which is a very bad assumption to do. So this always forces you to check, is it actually a validation error or not? Which is a little bit not wealthy. It actually existed in the alpha releases, but was quickly removed because of this. And was introduced using callbacks in 4.5. So this only applies to 4.5 at the moment. Previous releases didn't have this. Yeah, okay.

19. Using the Composition API and Custom Components

Short description:

Use form gives you access to everything, including the values and errors of the form. The composition API offers flexibility and makes it easier to perform advanced tasks. However, calling use field dynamically is not possible outside of the setup function or the script setup scope. To address this, the use field function is best used in a component, allowing for easier reuse. By creating a custom component called input field, we can isolate the use field functionality and define props using the define props function. This enables the component to be reused with different field names. The component can contain an input element with a value bound to the email field and an optional span for error messages. The name prop is required and automatically unwrapped for convenience. This approach eliminates the need for repetitive code and simplifies the usage of use field in a component-based architecture.

So we had the question before. It would be very nice to get data from use form. You can do that. So use form gives you access to everything. Like I said, the composition ABI remedies the issues of you having access to things that you probably should have access to. So you can grab the entire values here. And let's just print them out. Yeah, I need to remove this. I hate class. Okay. Let's start typing some things. And yeah, you have access to your values. You have access to other things. For example, yeah, this is really annoying. Let's clean it up. Let's remove it. Let's remove this, all this error messages, variables. And grab all the errors from the form itself. So we grab all the errors. And we go errors to email. And notice that if you are using TypeScript, you will get this benefit. It also completes for you. It knows that you are validating these fields using this schema. So you probably have these fields. So yeah, now we cleaned this up. Let's submit. Yeah, everything still works. So now the composition ABI, you notice that with flexibility, you get access to things that make it a lot easier for you to do these other things. More advanced things. But now that we are here at this point, we have like a small thing that we really like to get rid of. Like these calls to use field. What if I have like 100 field form, right? Or 50 or 20? Doesn't really matter. What if the form is dynamically generated? How can I even call this dynamically? You can't just, for example, make a function called add field and do this. You can't really do this. It will actually crash your app because composition ABI can be only called inside the setup function or the script setup scope. So you can't actually do this. It will break. So how can we fix this issue? This brings us to the actual use case of the composition ABI for use field at least. It's not like this. At the moment, what you are doing right here is you create validatable models for you, right? You create a model called email that is validated by the schema. Same thing for password. Same thing for confirmation. But the issue with this is it is verbose. It repeats a lot and it's really annoying to use. So the main use of the use field is to use it in a component. So it works really well only if you use it as a part of another component. So let's create a custom component called input field. Hold view. And let's set up the boilerplate TypeScript. Yes. I like using the setup. So we'll get rid of that. That's basically what setup allows us to do. Let's see what we will do here. So we want to remove this entirely. So let's grab this and use it there. We'll have to import it from V validate. So use field. And, yeah, now we have access to the use field inside this component. This component can have, like, it can be a div. It can have an input. This input has a value bound to the email field, which should be value now because it no longer has specific, it's not, it's a generic component. It's really an email field only. Maybe you have a span here for the, yeah, span works well for the error message. We currently don't have it, but we can grab it. So now we have isolated this, we have isolated this component. But we still need some properties. So we will use the define props function, which is how you define props in the script setup. So conist props equals define props. And you start defining properties to your component just as if you are doing it to the options API. So we can start with the field name. This has to be there, right? It is of type string, and it is required. So when using use field, we pass the name to it. So, yeah, this allows a component to be reused multiple times. And let's just add the binding to the name while we are at it. So directly the name, which is inside this prop, it is automatically unwrapped for you. So I guess this is exactly what we had here. But we still have something to fix, but let's get to it later. Let's import this new component from the components directory slash import field dot view. Okay. We no longer want this, and we no longer need this. So, and we can start removing all of these. So input field. And the only prop that we need is the name. So this was the email. Repeat it three times. Remove all of this. Password. What was its name? Confirm password. Right? So, yeah.

20. Fixing Input Field and Real-Time Validation

Short description:

We fixed the issue of the input field not existing by removing it and reloading. However, now the passwords are no longer hidden. To fix this, we added a type property to the input component and set it to 'password'. We reviewed the input component and discussed the difference between the script setup and the default options API. We prefer the setup script for its simplicity and efficiency. We explained how to bind the value to the input using vModel or handle change. We also addressed the issue of real-time validation and provided multiple ways to fix it.

So, yeah, that should completely replace this component. This, sorry, this multiple use field calls and this miss that was in the template. Yeah, but we have a few issues here. It says input field doesn't exist. So let's remove this from input field. Maybe it doesn't have aliases configured. Yes, it didn't have an alias configured for the at property. You do this in the Vite config, but I didn't do it. Can you look at the input field component again? Yes, we'll come back to it because we'll enhance it. So let's just reload, submit. Everything still works exactly the same. So, yeah, the email was the first one. But there is an issue, if you notice. The passwords are no longer hidden, right? You can see them in clear text. We don't want that. So let's go back here. Let's add a type property. It can be of type string. And it, the default is text. And we can add it here. Type equals type. And we can add it here. Type equals type. Yes, it should work. Duplicate attribute type. Yeah, we already have it here. So this is the input component. Let's review what we have here. So we have the template. Let's go back to it later. We are importing use field. We are defining our props. Again, if you are using the options API, it can be, or let me do it quickly for you. Define component. So you will do something like, we will remove this setup thing. So export, define component. And you will have your props. We can remove this. And we have setup function that accepts the props. And we can do this. Return. Yeah, I know I'm typing really quickly here. But I won't keep this. This is just for default. Let's just show you the difference between the script setup and the, well, the default options API. This is the regular function. So, yeah, this, I guess this looks a little bit more than you guys are, like, familiar with. If you are familiar with the setup, that's fine. You can use it. If you want the tried and true method of, like, describing the options object of the component, yeah, go ahead. Doesn't really matter. But honestly, I prefer the setup because it just removes a lot. So we can just remove all of this. This. This. Yeah. It allows our component code to be a little very minimal. So, yeah, same thing. Hopefully this doesn't confuse you. I may have made the wrong choice of going with the latest and things. But you should definitely use the setup script. It's really nice. Saves you a lot of time. Yeah, so let's review. We are calling this function. We are passing the field name, which are provided by the parent component that are going to use this input field component. We are grabbing the value and the error message. And that's it. We are binding the value to the input itself using vModel. But you can do it in a lot of different ways. You can have, we can, you can completely ignore the input field. You can have, we can, you can completely ignore using vModel and use handle change instead. So on input we can say handle change and it still should work exactly the same thing. So, yeah, it works, but it's really like it validates real time. So let's bring it back. The issue is we over remedied this issue. We should have vModel up here. Yes. And we didn't pass the type here. So now we can pass it because it is defined as a property. Thank you. I hope I haven't confused any of you because this is the first time I'm actually explaining vValid somewhat, other than the documentation. Yeah. So, yeah, now we have things working, I guess, fine. But what I guess is the problem now is real time validation. We don't really want to have that. So, yeah, okay. So let's fix that. We can fix this in multiple ways. There are really infinite ways you can do this.

21. Using Meta Object and Handling Field Blur

Short description:

With the composition API, you can use the meta object to access various properties of the field, such as dirty, initial value, bending, touched, valid, and validated. By using the touched property, you can control when to show error messages. Additionally, you can use the handleBlur function to trigger error message display when the field is blurred. The dirty flag indicates whether the field value has changed from the original, and can be used to display a label indicating whether the value has changed. The useForm function also provides access to the meta object, allowing you to disable the form based on its validity.

Again, you can grab handle change and only call it on change. You can do this. It will work. But I like to do this other way. So I actually like the error messages to be generated at all times, so real time. But I control when to show them. So this is a different way of doing it. There is something called meta on the field itself, on the use field function. So meta gives you a lot of various properties that you can use. So in the meta themselves you have access to something called dirty, which tells you when the field value has changed. You have access to the initial value. You have access to something called bending, which tells you if the field is still under validation or not. So if you have this asynchronous validation that's taking a lot of time, you can actually detect that. Maybe to display a spinner or something. There is something called touched, which is only true if the user has blurred this field. So the user focused it and left it. And the valid flag, which is similar to error message. You can just detect if it's valid or not. You don't have to check if error message has any messages or not. You have validated, which tells you if the field was validated before or not. And yeah, that's it. The rest are just an issue with my code completion. Just repeat some.

So what can we do with this? We can actually show the error message. So we can actually do this using VF or Vshow. Maybe Vshow is better here. Meta.touched. So touched corresponds to the user blurring the field. Right? So it should only show the error message when the user actually, when the user left the field. So notice that it actually ruined everything. It no longer shows anything. This is because this is always false now. Again, let's go back to the same point. So with the composition API, VValid can't have a lot of assumptions about your UI. So you have to help it a little bit. So we have another function called handleBlur. So all you have to do is trigger it whenever you think it should trigger. Like you can call it on the field itself. And now I'm typing. It doesn't show anything. But when I blur, the error message appears. And this is more or less what we want. And it gives us a really nice effect here. If I clear the error, the error message clears in real time, changes in real time now. Because the field was touched already. So now we have opened the gate and it will always validate it and change the error message. This is actually might be desired. And this existed in VValid V3 as a validation strategy that was called eager. It's eager for success. So we actually replicated it with a simple condition. So, yeah. This validated immediately because we have blurred it. Same thing for the field here. So, yeah. You can customize pretty much when to call touch. It is user controlled. Maybe you want to call it on focus instead. It's entirely up to you. But maybe handleBlur is a little bit confusing name-wise. So you can actually use something called setTouched. And instead call it whenever you really want to. Maybe you want to have, like, for some reason have a timeout and you really want to setTouched to true after five seconds. You can do whatever you want, really. So, yeah. It's entirely up to you when to set the field as touched. But let's try something else. Let me show you the change, the dirty flag. So the dirty flag tells you when the field value has changed from the original. So we have meta.dirty. Oh, sorry. Yeah. And now we have this nice label on the field telling us whether the value has changed or not. And, yeah. This one changed. This one didn't. This one changed. This one didn't. This one changed. It's not really useful on the field level. Like, I can hardly find a good reason for it. But with different use cases, you may never know. But what I can find a good use case for is you have also meta on the useForm function. So we can actually do some things here. Like, we can disable the form when the, as long as the field, as the form is invalid. So as long as the form is invalid, we are disabling this input. So when I reload, yes, it is invalid. Yes, it doesn't have any error messages, but it is invalid. The user haven't entered really anything. So let's try to fill it. And, yeah, now it's valid.

22. Simulating Synchronous Form Submission

Short description:

And now they can click. So you can do something really interesting here. This is when we have this submission function as a synchronous submission function now. It will take a little bit of time to submit the form, maybe two or three seconds. We want to show that to the user. We can turn a new promise with the resolve and simulate a network call. After two seconds, we call resolve. Now it's done.

And now they can click. So you can do this. You can do something really interesting here. So let me try to show you something else. This is when we have this submission function as a synchros. So this is a synchronous submission function now. And it will take a little bit of some time to submit the form, maybe two or three seconds. There is a problem with that. So we want to show that to the user. So we can turn a new promise, for example, with the resolve. And that promise will resolve after I'm simulating a network call here. So let's say after two seconds. And after, yeah, we'll set timeout. We'll just alert this and call it. And now it's done. Yeah, we'll set timeout. We'll just alert this and call resolve. And that should be it. Yeah. We don't really have a value here. Still have an error. I think I'm missing a bracket, which is kind of odd. Can't really seem to find it. So promise. Yeah. This is the error. And now it's done. So now we can go back to the code. So promise. Yeah. This is kind of embarrassing. I guess it happens to everyone. Yeah. Line 36. Yeah. One more. Yeah, because of the, oh, you mean? One more bracket here? I don't think so. Nah. Well, I think we're done. Nah. Well, I think I'm tired because I can't really see it. Set 36. Yes, it's not correct because it's set timeout. It actually needs it here. And yes, this is the blue. And yeah. So now we can go back to the code. And now we can go back to the code. And now we can go back to the code.

23. Using Submitting and Disabling Fields

Short description:

So this is the blue one. I'm kind of stuck. Let me start from scratch. Now it's valid. Set timeout. We can grab another thing from the form. If it is submitting, we want to disable it. We still have some error to show you. We lost the error messages. That's how to use submitting. There is a lot more to it. You can disable the field in the form submit function. For example, maybe you want to disable it when the form is dirty. So as long as the user hasn't changed anything, you don't want to submit it.

So this is the blue one. This is this one. What does this actually correspond to? Yeah. I'm kind of stuck. Yeah. I'm kind of stuck here. What a weird thing to be stuck on. So let me start from scratch, I guess.

So now it's valid. Set timeout. Narrow function. Step by step. So now we can go back to the code. Step by step. Resolve. And yeah. It's complaining because we didn't give it a value. Now we give it a value. Okay. Whatever. I'm not sure. There are some things extra. Yeah. Let's look at the values. Okay. So now we have a function. That should be it. So we can do something really nice trick here. We can grab another thing from the form. Which is submitting. So this tells you if the form is still submitting or not. Given that your submit function is actually asynchronous. So it returns a promise. We don't actually need this here. So yeah. If it returns a promise, then it is asynchronous. And you can use submitting then. So if it is submitting, we want to disable it to prevent it from submitting. So we can do that. If it is submitting, we want to disable it to prevent anyone from clicking it multiple times. Yes, you are right. Yeah. I think that was a mistake. Kind of embarrassing. But yeah. We still have some error to show you. Okay. I think we lost the error messages for some reason. Meta.touched. Yeah. Because it is not a function. So we can't use it. So we can't use it. Meta.touched. Yeah. Because I have removed the set touched. Let's add blur. And blur. Which we can add from here. Okay. Let me reload. Test this out quickly. Yes. Works. 4, 5, 6. Yeah. Now everything is valid. I will click submit. It is disabled until it should be locked here. Now. Yeah. That's it. That's how to use submitting. So there are a lot. There is a lot more to it. There is other thing called submit. Submit count. You can disable the field in the form submit function in a different situation. For example, maybe you want to disable it when unless the form is dirty. So as long as the user hasn't changed anything, you don't want to submit it. It doesn't make sense here. But it makes sense if the form was filled from the ABI, for example. So form data. Because an object. Email. Submit. And then you can submit it. So you can submit it. And then you can submit it. And then you can submit it.

24. Using the Form Object and Form Generators

Short description:

You can use the form object to submit the form. The composition API allows for easy form submission. The component acts as a custom form with validation. The submit function sends a request to the form component. It takes a little bit of time to get the hang of it, but it boosts productivity. The API is straightforward and flexible. The last important topic is field arrays and form generators. Check the documentation for a tutorial on building a form generator. There are also third-party integrations available, such as the form violate library.

And then you can submit it. And then you can submit it. So if you are not sure how to use it, you can use the form object. Email. Email. For example. I will just use the same thing for everything. Let me grab the same field name. And if you are just joining and don't know how to use initial values, you basically pass it to the form component or the use form function. So initial values. You can call it. I will just call it. Form. Or the submit. Or the submit. Or the form. You can grab it. I don't really need this. And that's really it. So when I reload, this is the entire values. If I change anything, the submit button is back on. So yeah. It's really up to you to craft what experience that you really want. And this product at the end is the, like what you see here is the intended use of the composition API. This component actually has a function called submit. And the function is called submit. And it's basically a function that will send a request to the form component. And it will ask you to submit. And it will ask you to submit. And it will ask you to submit. So this is the API. This component acts as a custom form. And this, the input field is a custom field, right? It's a custom field component that can do validation. You compose the validation logic into your own component. So this is a intended use case. Because yes, you set everything up here. But you only set it up once. So once you set it up once, you can just do one-liners like this. So this field has validation. It has the use case. This component is the end user. So they are the users. And this component is the submit. So this component has validation, has the touched logic. It only shows the message when the user plurals it. So it's really nice. It's really straightforward. And yeah, it takes a little bit to get the hang of it. But once you do, it will really boost your productivity a lot. Thanks. Thank you. I did prepare the slides. I'm going to show them to you. So this is the API. This is the API. This is the API. This is the API. And I did prepare the general section that I will talk about. But I didn't really prepare the, to be honest, I didn't really prepare what exactly I will talk about in each section. So it's kind of driven by you guys, by your questions. And so make sure to keep the feedback going. We still have about 30 minutes, I think. And let's wrap it up with a couple of examples. So something that is really, really important is the use case. So this is the API. This is the API. This is the API. And this is the API. And this is the API. And this is the API. And this is the API. And this is the API. And the last one is really, really hard to manage, which is field arrays. So form generator. I will try. Someone is asking whether we can make a form generator in the chat. I guess I will try to fit it in. But if we don't, again, I'm saying this a lot, check the documentation. There is a tutorial. It's a really, really good one. It's a really, really good one. So if you want to try it, you can. But if you don't, you can. So if you want to try it, you can. So if you want to try it, you can. So if you want to try it, you can. There is a tutorial on building a form generator like from scratch, and it will go a long way into how you set up the form schema, how to trigger validation, and there is a demo at the end of the that you want to try it. Having said that, there are also third party integrations. There is a library called form violate. It's a form generator library. It is something specialized in form generator.

25. Building Field Arrays in VValidate

Short description:

Let's talk about field arrays and how to build a field array. Field arrays are used in forms that can repeat a lot, such as adding multiple emails or URLs. We can use the V4 directive to repeat fields based on user interaction. We create a reactive reference to the fields array using the ref function. When the user clicks on a button to add a field, we push an object to the fields array. The field name is made dynamic by appending the index to the field name. We can log the values in real-time to see the changes. Adding a class can improve the appearance of the repeated fields.

And it has first class support with V validate. So you can marry the two and get a validated form generator. So hopefully this answers the question. I'm not sure if we are going to cover it or not. But yeah, I didn't make space for it, I guess. So yeah, hopefully the examples will be enough. Feel free to ask in the GitHub discussions or in stack overflow. I'm kind of active on both. So yeah.

Okay. Let's talk about field arrays. So let's say, let's change this whole form thing because it no longer makes any sense for what we really want to do. Let's say we have like a bunch of users. Like a form that has multiple forms. So these are the field arrays. I'm not sure if you have built one yourself or not. But these are the ones that we are going to talk about. And I'm going to show you how to build a field array. So let's say we have a bunch of users. And we have a bunch of users. And we have a bunch of users. And we have a bunch of users. And we have a bunch of users. So it doesn't matter if you have a lot of users. It doesn't matter if you have a lot of users. It doesn't matter if they're multiple or not. But these are the kind of elements that you, in a form that can repeat a lot. Like for example, the user can add another email. The user can add another URL. The user can add. Yeah, I will get back to your comment right away. Yeah, exactly. Repeater fields. Sorry I was trying to find the word for it because a lot of people call it different things. So, how would we get around doing that with VValidate? Given that we have this exact same setup. So I won't change anything a lot. But I would change the scheme of course. Because it no longer applies. This no longer applies. And this I guess no longer applies. Just look at the values. That's it. We don't really want to show anything on Valid Submission. So let's go back to the simple. To being simple things. Doing simple things here.

Okay. Let's imagine that you have an input. That is a URL, for example. And you want to repeat it. Based on the user interaction. So the user, you may give the user another button here. That says plus, for example. And on click, you will say something like add field. Then you'll go right here at this function. And now you'll think about how would you repeat this field. Well, we have our tried and true V4, right? So V4 field in fields, for example. Give it a key, which is field ID. Which we will have to generate basically. Or not. Maybe you can use the index as a start. But we really shouldn't use the index in most iterations. Or in such iterations that can change by the user. We don't have fields yet. So let's create that. So fields equals. We'll import ref from view to create a reactive reference to the fields array. So, yeah, fields. We'll add another field. So fields.push. Sorry,.value.push. And we'll push an object. And that object doesn't really matter what we push, actually. We are just using it to repeat, right? We are not using vmodel anywhere here. So that's not really important. So typically you would do this. You would push something like this. And you would push URL empty string. But it doesn't really make any difference. It doesn't matter what you push right here. Yes, we shouldn't forget to, thank you for reminding me, to bind the field name. So field name URL doesn't work because it is a repeated field. So we need to make it a little bit more dynamic. So it can be URL of index. So it generates URL zero, URL one, URL two, URL three, and so on. And let's just see what exactly happens real time by logging out the values. We see exactly what happens as it happens. We don't really need this, but just leave it. So it kind of looks really bad. So let's add the class here.

26. Handling Repeater Fields with VValidate

Short description:

To handle repeater fields, VValidate provides a component called field array. It allows for the dynamic addition and removal of fields. By using the field array component, we can simplify the process of iterating over the fields and rendering them. The key issue with repeater fields is ensuring uniqueness, which can be achieved using unique IDs or a counter. VValidate's field array component is a powerful tool for handling repeated fields, offering flexibility and ease of use.

So add just a simple class name. PostCSS. And display maybe block and give it a margin top 30 pixels. Yeah, I guess it's fine. Submit could look better too. I guess we can do this for all the buttons. Doesn't really matter. Yeah, I think it looks a little bit nicer. I don't really like the values being on another line because the formatting.

Okay. Click, click, click, click. Yeah, these are the repeater fields. This is basically what they are. It is a little bit confusing because we can't tell, like, there aren't any labels. But generally we should have labels for our fields. So let's maybe add that quickly. Label for maybe give it an ID of the same name. Find the label to the ID and just display the name. Just that it looks a little bit nicer. Yeah, it's a little bit clearer. Not the greatest thing for sure, but. So let's add them. And yeah, notice that they are all null. Right? This can be a little bit confusing. But as you type it, they are being filled. This is the issue that if you are trying to implement repeater fields just using these ABIs, this is what you will run into. You have this fields object that is in, like, it's really useless. It doesn't do anything, right? Because we are not using the model, as you can see. Where else are we using this fields array? We are just using it to iterate on the fields, right? To render these fields. So it's really cumbersome to have this model just for iteration. It doesn't make any sense. And you would have, like, other use cases. Like, as you can add a field, you can remove a field. And maybe we grab its index. So we replace the index with one. So we remove that single item from the array. And for each input field, maybe we add a button with it. I guess remove. Let me add a class for this quickly. Because I want the button to be right next to the. This is just for submit and just for add. Okay. Yeah, because I just kept the same thing. Let's call it a minus. And this before thing, we'll have to, like, move to a parent element. Remove field. So we can remove the index. And maybe we just use the more conventional X. So as we add a field, we have an X for it. It's not right next to it, but that's fine, I guess. And if I click, it removes them, right? But we have an issue here. The key is based on the index. So it can create a whole lot of confusing things. So if I remove the first one, but I think the value of the second one is what got grabbed. Let me try something clearer here. Because I tried to solve this a lot, but yeah, you notice what happened? It removed the last one. Didn't remove the first one. So, yeah, this is because of the key. So we need to have, like, uniqueness element to our elements. So we can use yes, we can use unique IDs, like a library, or you can use a counter. Like, this is the makeshift unique thing here that you can use. So it starts with zero. And, yeah, every time you add a field, it increments, and it will never repeat until it's 2 billion something. Okay, sorry about that. All right. Now we are removing, sorry. Yeah, we are creating a unique ID for each one, which means we can now use the ID on each field and reload. Okay, a bunch of them. Hopefully for the first, the other two will get removed nicely. And, yeah, there is some issue here. It got removed in the values, but it didn't get removed correctly from here. This is because it is really hard to deal with these kind of fields because of the key, because of the current value inside these, because they are, yeah, there are a lot of issues here. ID and remove by ID. Yeah, we can do that, but it doesn't really matter here. We can name them by IDs, but this isn't the point of this demo. There is a lot of pain dealing with the repeated fields, right? You are completely right, by the way. We can use more deterministic names to fix this issue, but VValidate tries to do it for you. So what can we do here? There's a component called field array, and this is one of the examples where component API is better than a composition API because there is a use field array. But using it is a little bit more hard than using just the component version of it because the component version of it, again, works with everything. It works with the composition API, and it works with your custom fields as well. So instead of doing this, let's just call the field array component, move this iteration inside. So we remove this as well. We no longer need all of these things. And I think I know what was wrong in the previous example. We are bushing objects. Yeah, let me go back a little bit on step because that confused me while I was explaining. So I said we have fixed this issue by binding them correctly, but when I remove them, everything clears. This is because we have URL bound to the element itself, but it should be bound to the URL property. I think this is the issue. So let's see this again.

27. Using the Field Array Component in VValidate

Short description:

The field array component in VValidate handles the array for you and generates the key property for each field element. You no longer need to manage creating unique IDs yourself. Adding and removing fields is done using the push and remove functions in the scooped slot. The field array component manages the field arrays and should not clear the values. There may be a bug or mistake in the component that needs to be addressed. The issue may be related to not using a reactive reference for the field name, causing it to stay static. By using a reactive reference, VValidate can track the field name changes.

Yeah, you notice the values change. Now it's missed it. So let me try this one more time. If it doesn't work, I'll just move on. Yeah, wasn't it. So sorry about that confusion. But I guess this is a bug, I think. Or we should use more deterministic things. Yeah, I think I'm running out of time. Give me a second. Yeah, the examples will be available in the report. Sorry, there was a question on Discord. I'm answering it. Okay, now that I have responded, now we can go to the meat of the issue. So field array. Yeah, this was a very long intro. I wasted a lot of time here. Sorry about that. Yeah, so let's remove all of these. We no longer need them because we have this field array component. So this field array component gives you a scooped slot. So you call the scooped slot and you grab some things, mainly fields array. So it does this thing for you. It handles the array for you. You don't have to do it. And what it also does for you is you no longer have to generate your own ID here. So there is a key property generated for you from that field element. Again, we no longer have any fields here. All we care about is the initial values. Yeah, we don't really have initial values for now. So but we have to give the field array in order for it to work. We have to give it the path of the URL. So the path of the repeating field. So the path is just URL, right, because this is the field that actually repeats. And you no longer actually to make it nested object. You can just have it as a flat object because you no longer have to manage creating the unique ID yourself. It will do it for you. So let's talk about removing and adding. So adding. Let's move it here. The scooped slot itself has like a function called push, a function called remove. So you can have push right here. And since we are just using plain strings, you can push a plain string right here. This is the new field value. Remove field. We can just remove by index. It's completely safe. This should be. So you know how it goes with demos. So, yeah, this should be exactly the same as we had it. But let's see how it works. So we add a new field. So like this, like this, like this. Works the same. The value is exactly the same. But if I remove it, yeah, everything clears. I think I'm doing something terribly wrong here in this component. But there is an example in the documentation that actually has this working. So there is something I'm missing. But I can't find the time to actually address it. So, yeah, it manages the field arrays for you. It shouldn't clear the values like this. So this is a mistake that I have somewhere. There are examples for should you fill fields of index. You don't have a URLs array. Yeah, that's not it. Because it should be creating the array value itself. I guess I'm just showing you the feature. I'm not really, I'm not entirely sure why it's, yeah, I didn't save. I'm not entirely sure why it's, yeah, so when we submit, this is your form values. And we are clear. Maybe it has an issue and I removed from beginning. Yeah, it's possibly either a bug or something I'm doing wrong that I have missed while explaining this. At any case, yes, I think I know what's wrong. Just give me this one try. And I'm sorry for, because I didn't think of this example properly. So here it goes for someone was mentioning I was prepared. I guess not. So name, it should allow the name to change. Right now we are just grabbing the static value of it, which is, I think this is what is breaking it. So props, and we give it the name. This should give us a reactive reference to the name. This is a composition I think I believe. So let's try if this actually works or not. Yeah, it works. So yeah, that was the issue. Basically, yeah, basically what the problem is just calling only grabs the name at the initialization phase. So it will always stay URL of zero, which doesn't make sense because the fields can move around. So the names will change. So we want a reactive reference to it and VValidate understands that when you give it a reactive reference, it will track it around.

28. Using VValidate Inspector and Handling Reactivity

Short description:

In the composition API, you need to grab a reactive reference to props or reactive objects to maintain reactivity. The Vue team is working on updates for this issue. VValidate installs the VValidate inspector in Vue Devtools, which provides a form tree for debugging forms. The inspector shows the form, fields, and their validity status. Each node in the tree is labeled with a tag, and valid fields are highlighted in green.

I think the original example used the native, the VValidate field component, which already has this set up. So this is one of the pitfalls. So I forgot about it. You'll probably forget about it. So don't, not necessarily, of course, but keep it in mind that you should get a reactive reference to something that may change like the field name. So if I remove this now, all works just fine. And I think this was the issue as before. So yeah, the issue, this was the same issue.

Okay, so what else can we do here? Are the props defined as reactive by default? Not in the composition API. In the composition API, if we grab the props like this, you are only evaluating them only at the time. So it won't re-evaluate. Yeah, this is just composition API shenanigans, I guess. So you always have to make sure you are dealing with those riffs. That kind of sucks. Yeah, that's kind of, kind of sucks. Yeah, but there isn't really a way around it from like the Vue team. It's very hard to work around it. I'm thinking they are working on some updates for it. We'll see. Reactive. Yeah, the problem, same problem with reactive, actually. So if you create something called like this form, for example, and it is a reactive object, if you, for example, let's say URL, and try to grab the URL, it is the same thing. It is a reactive object, but you have to grab a reactive reference to the property. Because when you destruct a reactive, because this is basically what happens when you say, you are destructing the name from the props. It is similar to this. So you are actually losing reactivity because you grabbed the name property. To maintain reactivity, you have to keep the whole thing together. But that's impossible if you want to pass just one property. So you have to use something like to ref, or you can use computed and do it like this. Computed is another composition function. So you can do Yeah. Both works. But to ref makes sense here more. Shorter as well. Let me check the time. Yeah, we should only be wrapping up right now. We only have 10 minutes. I really want to get to the last example. But let's see what we'll talk about. So we have seen all of these things. Let me go back, way back. So I really wanted to show you more, but I guess I underestimated the time that we have. So rolling back to when we had like this form with multiple inputs. Yeah. That's close enough. Yes. I think we need the schema here. So let's give it a quick schema. So name is string required. Can't assume this name length. Keep that in mind. So required. Password similar string. But you notice how it becomes like when you know what you are building, it becomes really straightforward. So we just created this form really fast. Kind of. So let's review one last thing of what VValidate does for you. So this is the view of div tools. And I think I kind of spoiled it. So let's go back. So this is the native, not native, I use that word a lot. This is the default view of div tools. This is what you will most likely have most of the time. But just by using VValidate, VValidate does something special for you. If you are using the view of div tools. It installs something called an inspector for you. It's called the VValidate inspector. You can enable it from the inspector selector here. If I zoom out to give you like the more default look, it looks like this. You switch it like this. But for you to see properly, it is how everything looks. So someone was asking earlier about how to debug the forms. This is how you would debug your forms. So let's start. It's really nice because at first glance, it gives you a form tree, right? It gives you the form, the name field, the email field, and the password tree. It shows you the form tree. So it won't show you any other components. So it won't show you the app component. It won't show you your other custom components. It will only show you forms and fields. So notice that each node has like a tag right next to it. There's form, field. It just tells you what it is. This form has three fields at the moment, so it also tells you what it is. But here's the nice thing. Once we start typing the name field, notice that color turns to green, the color of the tag. This is to give you at a glance, if you're debugging something, to let you know which fields are valid and which fields are not. So you don't have to go through this whole thing and figure out which is valid and which is not. So you just, okay, yeah, that field is valid.

29. Using V-Validated VTools and Field Arrays

Short description:

The V-Validated VTools provide a way to debug form validation. They allow you to check the state of each field, including errors, initial value, current value, and validation status. The VTools also help identify missing or incorrectly added fields. They work with field arrays and offer features like resetting fields and forcing validation. The documentation includes examples of building a multi-step form wizard using V-Validate. Field arrays provide flexibility and have various capabilities. However, due to time constraints, a more detailed explanation is not provided here.

So that one is still not valid because it's not a valid email. But once it is, it turns green, the password similarly. And once it's all green, the form is considered valid, so everything is green. So let's snoop around here. If you click on each of these nodes, so we have the name node, email node, and password node. The name node or the field node in general gives you access to this information. You have access to errors. So let me errors this field out. Yes, it shows you the errors. It shows you the initial value, which was undefined. It shows the current value, which is an empty string. So let me update it. Yes, it updates real time with you. It is touched. It is dirty. And it is valid. But if I, again, go back to the start, yes, it is invalid. And, yeah, we have an error message. Same things for the other fields, for the email and for the password. But for the form component, it has a little bit more state. It has the entire errors of the form. It has the current values of the form. It has the initial values. And it has the combination of all the state together. So let's make a mistake and see how can we catch it with this. Yeah, let's add another rule, for example, for a field that doesn't exist. Something like confirmation. Right? We added this, but we somehow forgot to add the ‑‑ I'll just use it like this. I won't actually make it a confirmation field for now. So let me reload, and let's go back to being blind. We don't know anything anymore about this form. And I tried to submit it. Yes, it is valid. I tried to fix it. So if I try to click submit, nothing is happening. And I can't really tell what's going on. Right? This happens a lot, and I think in our applications, it happens a lot with me. It happens a lot when your form isn't submitting. So you try to figure out what's going wrong, and you usually try to do this. You grab the entire thing, and you throw it in the template. So, like, show me what you got. Yeah, so the confirmation is required. Okay. But we don't have a field called confirmation. Right? So now you have figured that out. But it kind of was out of reach for you. Right? It was annoying to debug this. And you need to know where to actually look. So let's remove it and do it with the VTools instead. So, again, let me open this highlight. So submit. Nothing is working. So let's use the VTools. It says the form is invalid, but all the fields in it are valid. So this is interesting. Right? This doesn't make any sense. So let's check the form state. And once we check the errors, we get our hint. There is a field called confirmation that it is required. But we don't that field doesn't exist here. So that can either mean you added this rule by mistake or you forgot to add that field. So if we remove it, try this again. Everything is valid. I should be able to submit. I think it submitted because when I checked the console, yes, it did submit. So, yeah, these are the V-Validated VTools. Does this work with the field arrays as well? Yes, they did definitely change a lot. And, yeah, what else can we do? There is a couple of features. You can test the field state yourself. So right here you have this trash item, which if you click on the form element, click clear, it will reset the field for you. If you click on validate, it will force the validation. But we are using touch, if you remember. We are using touch to force, to hide or display the validation messages. But the errors are actually being rendered here. So you can actually test your UI states using this approach. And, yeah, this VTools works with all kinds of fields. So if you have field arrays that we briefly introduced, it will work fine. It will render them like this and you will have the exact same experience. And I guess this is it. This is all that I think I wanted to show you about V-Validate. What I couldn't manage, I guess I ran out of time of having a multi-step forum. But luckily there is an example in the docs on just how to do that. So if you go to the documentation, check the examples, you'll have multi-step form wizard. And it does it in two different ways, using the components and using composition API. So check it out. This was basically what we are going to try to build. What else? I wanted to show you more about field arrays, I guess. But I guess what I can tell you more here about it quickly is field arrays has a lot of things that you can do. So let's go back to the slot. Again, I'm not doing that thing.

30. Field Operations in VValidate

Short description:

You have the fields, which you can iterate on and perform various operations like insertion, updating, swapping, and changing the order. The replace function allows you to replace the entire array with another. These options provide flexibility in managing the fields.

You have the fields, which are the things that you should iterate on. You have push, you have remove, you have insert. So you can insert item at a specific location. You can update a single item, single item's value. And you can swap. So you can actually replace two elements. You can change the order, which is really nice if your fields are movable by the user. And I think that's it. I can't remember if there was another thing or not. I think there was a replace. Yes, there was a replace, which replaces the entire array with another. So you have a lot of options here. This is the entirety of it. I should have mentioned it for diving into the diff tools. But yeah, that's it.

Watch more workshops on topic

Vue.js London Live 2021Vue.js London Live 2021
169 min
Vue3: Modern Frontend App Development
Featured WorkshopFree
The Vue3 has been released in mid-2020. Besides many improvements and optimizations, the main feature of Vue3 brings is the Composition API – a new way to write and reuse reactive code. Let's learn more about how to use Composition API efficiently.
Besides core Vue3 features we'll explain examples of how to use popular libraries with Vue3.
Table of contents:
- Introduction to Vue3
- Composition API
- Core libraries
- Vue3 ecosystem
IDE of choice (Inellij or VSC) installed
Nodejs + NPM

Vue.js London Live 2021Vue.js London Live 2021
117 min
Using Nitro – Building an App with the Latest Nuxt Rendering Engine
We'll build a Nuxt project together from scratch using Nitro, the new Nuxt rendering engine, and Nuxt Bridge. We'll explore some of the ways that you can use and deploy Nitro, whilst building a application together with some of the real-world constraints you'd face when deploying an app for your enterprise. Along the way, fire your questions at me and I'll do my best to answer them.

Vue.js London 2023Vue.js London 2023
137 min
TresJS create 3D experiences declaratively with Vue Components
- Intro 3D 
- Intro WebGL
- ThreeJS
- Why TresJS
- Installation or Stackblitz setup 
- Core Basics
- Setting up the Canvas
- Scene
- Camera
- Adding an object
- Geometries
- Arguments
- Props
- Slots
- The Loop
- UseRenderLoop composable
- Before and After rendering callbacks
- Basic Animations
- Materials
- Basic Material
- Normal Material
- Toon Material
- Lambert Material
- Standard and Physical Material
- Metalness, roughness 
- Lights
- AmbientLight
- DirectionalLight
- PointLights
- Shadows
- Textures
- Loading textures with useTextures
- Tips and tricks
- Misc
- Orbit Controls
- Loading models with Cientos
- Debugging your scene
- Performance
Vue.js London Live 2021Vue.js London Live 2021
116 min
Building full-stack GraphQL applications with Hasura and Vue 3
The frontend ecosystem moves at a breakneck pace. This workshop is intended to equip participants with an understanding of the state of the Vue 3 + GraphQL ecosystem, exploring that ecosystem – hands on, and through the lens of full-stack application development.
Table of contents
- Participants will use Hasura to build out a realtime GraphQL API backed Postgres. Together we'll walk through consuming it from a frontend and making the front-end reactive, subscribed to data changes.
- Additionally, we will look at commonly-used tools in the Vue GraphQL stack (such as Apollo Client and Urql), discuss some lesser-known alternatives, and touch on problems frequently encountered when starting out.
- Multiple patterns for managing stateful data and their tradeoffs will be outlined during the workshop, and a basic implementation for each pattern discussed will be shown.
Workshop level
NOTE: No prior experience with GraphQL is necessary, but may be helpful to aid understanding. The fundamentals will be covered.

Vue.js London Live 2021Vue.js London Live 2021
72 min
A Different Vue into Web Performance
Solving your front-end performance problems can be hard, but identifying where you have performance problems in the first place can be even harder. In this workshop, Abhijeet Prasad, software engineer at, dives deep into UX research, browser performance APIs, and developer tools to help show you the reasons why your Vue applications may be slow. He'll help answer questions like, "What does it mean to have a fast website?" and "How do I know if my performance problem is really a problem?". By walking through different example apps, you'll be able to learn how to use and leverage core web vitals, navigation-timing APIs, and distributed tracing to better understand your performance problems.

Vue.js London Live 2021Vue.js London Live 2021
89 min
Building for Web and Native with Ionic & Vue
When building an app, there are many options choices developers need to make. Is it a web app? Does need to be a native app? What should I use for UI? In this workshop will look at how to make use of Ionic for building your app and how to deploy it to not only the web, but native as well.

Check out more articles and videos

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

Vue.js London Live 2021Vue.js London Live 2021
34 min
Everything Beyond State Management in Stores with Pinia
When we think about Vuex, Pinia, or stores in general we often think about state management and the Flux patterns but not only do stores not always follow the Flux pattern, there is so much more about stores that make them worth using! Plugins, Devtools, server-side rendering, TypeScript integrations... Let's dive into everything beyond state management with Pinia with practical examples about plugins and Devtools to get the most out of your stores.
Vue.js London Live 2021Vue.js London Live 2021
20 min
One Year Into Vue 3
Vue 3 may still sound new to many users, but it's actually been released for over a year already. How did Vue 3 evolve during this period? Why did it take so long for the ecosystem to catch up? What did we learn from this process? What's coming next? We will discuss these questions in this talk!

Vue.js London Live 2021Vue.js London Live 2021
8 min
Utilising Rust from Vue with WebAssembly
Rust is a new language for writing high-performance code, that can be compiled to WebAssembly, and run within the browser. In this talk you will be taken through how you can integrate Rust, within a Vue application, in a way that's painless and easy. With examples on how to interact with Rust from JavaScript, and some of the gotchas to be aware of.
Vue.js London Live 2021Vue.js London Live 2021
24 min
Local State and Server Cache: Finding a Balance
How many times did you implement the same flow in your application: check, if data is already fetched from the server, if yes - render the data, if not - fetch this data and then render it? I think I've done it more than ten times myself and I've seen the question about this flow more than fifty times. Unfortunately, our go-to state management library, Vuex, doesn't provide any solution for this.
For GraphQL-based application, there was an alternative to use Apollo client that provided tools for working with the cache. But what if you use REST? Luckily, now we have a Vue alternative to a react-query library that provides a nice solution for working with server cache. In this talk, I will explain the distinction between local application state and local server cache and do some live coding to show how to work with the latter.