Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for Create Dynamic Forms in Vue3.
Alvaro Saburido
Alvaro Saburido

Posted on • Edited on

     

Create Dynamic Forms in Vue3.

New Year, first article! Let's get started. 🤩

So after several months of lockdown in Spain and really relaxing holidays, I worked hard on a plugin to bringDynamic Forms toVue3 andComposition API and finally, the stable 3.x version was released yesterday 🥳.

But... whatDynamic Forms even mean? Well is basically a vue component that renders forms and inputsdynamically based on a dataobject/schema that represents the business logic.

<template><dynamic-form:form="testForm"/></template><scriptlang="ts">...setup(){constform=ref({id:'test-form',fields:{username:TextField({label:'Username',}),email:EmailField({label:'email',}),}})return{form}}...</script>
Enter fullscreen modeExit fullscreen mode

No more huge template files, no more "We need to do a new release because the client wants to change the username input label" 🤯. Forms schemas can be async and forms generated on go with an easy-going validation approach. All that for only26kB.

Still interested inquickly create forms in Vue 3.x? This article is for you.

quickly

What we are going to build?

Just a simple login form similar to the onehere. We are going to cover

  • Email input with validation,
  • Password input with validation
  • Checkboxes
  • Form submission

Login Example

Create the demo app

For the app creation let's useVite⚡️

yarn create @vitejs/app my-login-demo--template vue-ts
Enter fullscreen modeExit fullscreen mode

Installation

To install just run:

yarn add @asigloo/vue-dynamic-forms# or, using NPMnpminstall @asigloo/vue-dynamic-forms
Enter fullscreen modeExit fullscreen mode

The installation and usage have changed to align with the new Vue 3 initialization process.

To create a new plugin instance, use thecreateDynamicForms function.

// main.tsimport{createApp}from'vue';import{createDynamicForms}from'@asigloo/vue-dynamic-forms';constVueDynamicForms=createDynamicForms({// Global Options go here});exportconstapp=createApp(App);app.use(VueDynamicForms);
Enter fullscreen modeExit fullscreen mode

Theming

Vue Dynamic Forms is style agnostic, which means components have no predefined styles by default, so you can set them as you like. If you prefer a moreready-to-go solution for styling you can import a defaulttheme file from the package like this and override the variables like this.

// styles.scss$input-bg:#e2eb5d52;$input-border-color:#aec64c;@import'~@asigloo/vue-dynamic-forms/dist/themes/default.scss';
Enter fullscreen modeExit fullscreen mode

Login Form

Go to yourApp.vue and add the<dynamic-forms /> component into your template:

<template><divclass="app"><dynamic-form:form="form"/></div></template>
Enter fullscreen modeExit fullscreen mode

Next step is to write down the form schema using aref in thesetup method

You can also defineform as a computed property in case usingvue-i18n labels or to reactively assign a value to any form property such as visibility or dropdown options

import{defineComponent,ref}from'vue';import{ EmailField,PasswordField,CheckboxField}from'@asigloo/vue-dynamic-forms';exportdefaultdefineComponent({name:'App',setup(){constform=ref({id:'login-form',fields:{email:EmailField({label:'Email',}),password:PasswordField({label:'Password',autocomplete:'current-password',}),rememberMe:CheckboxField({label:'Remember Me',}),},});return{form,};},});
Enter fullscreen modeExit fullscreen mode

Let's open our browser and check our new form with thevue-devtools. If you don't have it install it yet and want to work with Vue3 support, I recommend you to install the Beta version on the chrome storehere. It includes awesome new stuff such as a Timeline for component events.

Vue dynamic forms dev-tools

As you can see in the image above, each field was transformed into aFormControl object containing crucial info for its rendering and behavior. With this, you can easily check and debug your forms.

It took what? 5 minutes?. 🤭

I have spoken

Form submission

Now that we have our form in place, we want to do something with the input data. There are two ways to do it:

  1. Use asubmit button to trigger asubmit event. (Recommended option, it also check if the form is valid).
  2. Use thechange event to get the latest state of the form values. (This one doesn't care about validation but it's helpful for autosave features for example)

Using asubmit button.

If you add a button of typesubmit just below the<dynamic-form /> with the attributeform equal to theform.id it will trigger the form submission internally.

<dynamic-form:form="form"@submitted="handleSubmit"@error="handleError"/><buttonclass="btn"submit="true":form="form?.id">  Sign In</button>
Enter fullscreen modeExit fullscreen mode

For this road, we have two (2) possible events:

  1. submitted in case the validation went well and the form isvalid (retrieve all values) ☑️
  2. error in case there is an error in the form (retrieves all errors) ❌

On change detection

TheDynamicForm component also offers achange event in case you want to get the latest state of the form values right away. Is important to consider it will retrieve the valueswithout considering validation, (errors will still be shown at UI level) so you probably want to do a second validation outside.

<dynamic-form:form="form"@change="valuesChanged"/>
Enter fullscreen modeExit fullscreen mode
setup(){constformValues=reactive({});constform=ref({id:'login-form',fields:{// Form-fields},});functionvaluesChanged(values){Object.assign(formValues,values);console.log('Values',values);}return{form,valuesChanged,};},
Enter fullscreen modeExit fullscreen mode

Vue Dynamic Forms change detection

Validation

Normally, forms submit data to a backend service, we want to make sure that the data required is sent, and is sent correctly so we don't end with errors in the console or "limbo" states in our application.

Let's make ouremail andpassword fields required for the submission. Just add a propertyvalidations with an array of all the validation you want the field to have, in this case, let's import therequired validator like this:

import{required,EmailField,Validator}from'@asigloo/vue-dynamic-forms`;
Enter fullscreen modeExit fullscreen mode

Then add it to your field definition:

email:EmailField({label:'Email',validations:[Validator({validator:required,text:'This field is required'}),],}),
Enter fullscreen modeExit fullscreen mode

If you try to submit the form empty, or you touch and blur the input without value it will adderror classes to your component so you can style it accordingly

Vue Dynamic Forms validation error

If you correct the validation, which in this case, it's just adding a value to the field and you blur, asuccess class will be added to the control

Vue Dynamic Forms validation success

What about checking if theemail format is correct and adding a complex validation to your password?

By default,Vue Dynamic Forms contains the following validations:

  • required
  • min
  • max
  • email
  • URL
  • minLength
  • maxLength
  • pattern.

So let's use theemail andpattern validator to our cause:

import{required,email,FormValidator,// ...}from'@asigloo/vue-dynamic-forms';
Enter fullscreen modeExit fullscreen mode
setup(){constemailValidator:FormValidator={validator:email,text:'Email format is incorrect',};// ...email:EmailField({label:'Email',validations:[Validator({validator:required,text:'This field is required'}),emailValidator,],}),}
Enter fullscreen modeExit fullscreen mode

Vue Dynamic Form email validation

Similar to this, let's use thepattern validation, this function is special because it takes an argument which is theregex pattern you want to apply to the validation.

import{required,email,FormValidator,// ...}from'@asigloo/vue-dynamic-forms';
Enter fullscreen modeExit fullscreen mode
setup(){constpasswordValidator:FormValidator={validator:pattern('^(?=.*[a-z])(?=.*[A-Z])(?=.*)(?=.*[#$^+=!*()@%&]).{8,10}$',),text:'Password must contain at least 1 Uppercase, 1 Lowercase, 1 number, 1 special character and         min 8 characters max 10',};// ...password:PasswordField({label:'Password',autocomplete:'current-password',validations:[Validator({validator:required,text:'This field is required'}),passwordValidator,],}),}
Enter fullscreen modeExit fullscreen mode

Vue Dynamic Form password validation

Wrap Up

So that's pretty much it, you can check the complete solutionhere (it also shows how to use withTailwindCSS)

Of course, this is a pretty simple example, but I will post more use cases in the near future, such asasync form data,i18n,custom fields, andthird-party components

If you have any questions feel free to open a discussion on the comment section or ping me on Twitter@alvarosaburido. I'm always hanging around.

We're also looking forcontributors to improve and maintain therepo, If you are interested in the challenge please DM me.

This is the way

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Creative Software Engineer from 🇻🇪 living in Barcelona, Spain.Developer Experience Engineer at StoryblokAuthor of TresJSContent Creator @AlvaroDevLabsFormer founder of Porsche Digital Bcn.
  • Location
    Barcelona Spain
  • Education
    Telecommunications Engineer
  • Work
    DevRel at Storyblok
  • Joined

More fromAlvaro Saburido

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp