Categories
Vue 3

Add Form Validation to a Vue 3 App with Vuelidate 2 — Models and Dirty

Vuelidate 2 is a popular form validation library made for the Vue 3 apps.

In this article, we’ll look at how to add form validation to our Vue 3 app with Vuelidate 2.

$model

We can bind our form fields to the $model property.

This way, we can show errors only when the field is dirty.

For instance, we can write:

<template>
  <div>
    <input v-model="v$.name.$model" />
    <template v-if="v$.name.$dirty">
      <div v-for="error of v$.name.$silentErrors" :key="error.$message">
        <div>{{ error.$message }}</div>
      </div>
    </template>
  </div>
</template>

<script>
import useVuelidate from "@vuelidate/core";
import { required } from "@vuelidate/validators";

export default {
  name: "App",
  setup() {
    return { v$: useVuelidate() };
  },
  data() {
    return {
      name: "",
    };
  },
  validations() {
    return {
      name: { required },
    };
  },
};
</script>

We have the v$ reactive property that’s used to do all the form validation checks.

Once v$.name.$model has been manipulated, $dirty will become true .

And we show the error messages by rendering the entries in v$.name.$silentErrors .

Also, we can set the $autoDirty property to true to make a field that’s been manipulated have the $dirty property automatically set to true .

To do this, we write:

<template>
  <div>
    <input v-model="v$.name.$model" />
    <template v-if="v$.name.$dirty">
      <div v-for="error of v$.name.$silentErrors" :key="error.$message">
        <div>{{ error.$message }}</div>
      </div>
    </template>
  </div>
</template>

<script>
import useVuelidate from "@vuelidate/core";
import { required } from "@vuelidate/validators";

export default {
  name: "App",
  setup() {
    return { v$: useVuelidate() };
  },
  data() {
    return {
      name: "",
    };
  },
  validations() {
    return {
      name: { required, $autoDirty: true },
    };
  },
};
</script>

Lazy Validations

We can also set the $lazy property to true to make Vuelidate validate fields only when the field has been manipulated.

For instance, we can write:

<template>
  <div>
    <input v-model="v$.name.$model" />
    <template v-if="v$.name.$dirty">
      <div v-for="error of v$.name.$silentErrors" :key="error.$message">
        <div>{{ error.$message }}</div>
      </div>
    </template>
  </div>
</template>

<script>
import useVuelidate from "@vuelidate/core";
import { required } from "@vuelidate/validators";

export default {
  name: "App",
  setup() {
    return { v$: useVuelidate() };
  },
  data() {
    return {
      name: "",
    };
  },
  validations() {
    return {
      name: { required, $lazy: true },
    };
  },
};
</script>

to set the property in the validations method.

Display More Error Information

To display more error information, we can write:

<template>
  <div>
    <input v-model="v$.name.$model" />
    <template v-if="v$.name.$dirty">
      <div v-for="error of v$.name.$silentErrors" :key="error.$message">
        <strong>{{ error.$validator }}</strong>
        <span> on property</span>
        <strong>{{ error.$property }}</strong>
        <span> says:</span>
        <strong>{{ error.$message }}</strong>
      </div>
    </template>
  </div>
</template>

<script>
import useVuelidate from "@vuelidate/core";
import { required } from "@vuelidate/validators";

export default {
  name: "App",
  setup() {
    return { v$: useVuelidate() };
  },
  data() {
    return {
      name: "",
    };
  },
  validations() {
    return {
      name: { required, $lazy: true },
    };
  },
};
</script>

error.$validation has the name of the validation rule as a string.

error.$property has the name of the field as a string.

error.$message has the form validation error message.

Conclusion

We can set how form validation is triggered with Vuelidate 2 in our Vue 3 app.

Also, we can display more error information than the message.

Categories
Vue 3

Add Form Validation to a Vue 3 App with Vuelidate 2

Vuelidate 2 is a popular form validation library made for the Vue 3 apps.

In this article, we’ll look at how to add form validation to our Vue 3 app with Vuelidate 2.

Installation

To install Vuelidate 2, we run:

npm install @vuelidate/core @vuelidate/validators

with NPM.

Or we can run:

yarn add @vuelidate/core @vuelidate/validators

with Yarn.

Add Form Validation

To add form validation with Vuelidate 2 into our Vue 3 app, we write:

<template>
  <div>
    <input v-model="name" />
    <div v-for="error of v$.name.$silentErrors" :key="error.$message">
      <div>{{ error.$message }}</div>
    </div>
  </div>
  <div>
    <input v-model="contact.email" />
    <div v-for="error of v$.contact.email.$silentErrors" :key="error.$message">
      <div>{{ error.$message }}</div>
    </div>
  </div>
</template>

<script>
import useVuelidate from "@vuelidate/core";
import { required, email } from "@vuelidate/validators";

export default {
  name: "App",
  setup() {
    return { v$: useVuelidate() };
  },
  data() {
    return {
      name: "",
      contact: {
        email: "",
      },
    };
  },
  validations() {
    return {
      name: { required },
      contact: {
        email: { required, email },
      },
    };
  },
};
</script>

We import the useVuelidate hook, call it, and assign the returned value to thew v$ reactive property.

Then we add the name reactive property and bind it to the input with v-model .

And then in the validations method, we return an object with the name of the field and the validation rules.

We set each property in the object we return in the validations method to properties an object with the validation rules we want to set.

Then we get the errors with the $silentErrors property in each object.

error.$message has the error message of each field.

Dirty State

The $dirty state is provided by Vuelidate for each field to track if any manipulation has been done to it or not.

For instance, we can write:

<template>
  <div>
    <input v-model="name" @blur="v$.name.$touch" />
    <template v-if="v$.name.$dirty">
      <div v-for="error of v$.name.$silentErrors" :key="error.$message">
        <div>{{ error.$message }}</div>
      </div>
    </template>
  </div>
  <div>
    <input v-model="contact.email" @blur="v$.contact.email.$touch" />
    <template v-if="v$.contact.email.$dirty">
      <div
        v-for="error of v$.contact.email.$silentErrors"
        :key="error.$message"
      >
        <div>{{ error.$message }}</div>
      </div>
    </template>
  </div>
</template>

<script>
import useVuelidate from "@vuelidate/core";
import { required, email } from "@vuelidate/validators";

export default {
  name: "App",
  setup() {
    return { v$: useVuelidate() };
  },
  data() {
    return {
      name: "",
      contact: {
        email: "",
      },
    };
  },
  validations() {
    return {
      name: { required },
      contact: {
        email: { required, email },
      },
    };
  },
};
</script>

In each input, we call the $touch method when we move focus away from the input.

This will make the $dirty property become true .

Therefore, we can use this to show validation errors when we focused on the input and then move focus away from it.

Conclusion

We can add basic form validation into our Vue 3 app with Vuelidate 2.

We can show validation errors and control when they’re shown.

Categories
Vue 3 Projects

Create a Landing Page with Vue 3 and JavaScript

Vue 3 is the latest version of the easy to use Vue JavaScript framework that lets us create front end apps.

In this article, we’ll look at how to create a landing page with Vue 3 and JavaScript.

Create the Project

We can create the Vue project with Vue CLI.

To install it, we run:

npm install -g @vue/cli

with NPM or:

yarn global add @vue/cli

with Yarn.

Then we run:

vue create landing-page

and select all the default options to create the project.

Create the Landing Page

To create the landing page, we write:

<template>
  <form v-if="!submitted" @submit.prevent="submitted = true">
    <div>
      <label>your name</label>
      <input v-model.trim="name" />
    </div>
    <button type="submit">submit</button>
  </form>
  <div v-else>
    <p>Welcome {{ name }}</p>
    <p>The time is {{ dateTime }}</p>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      name: "",
      dateTime: new Date(),
      timer: undefined,
      submitted: false,
    };
  },
  methods: {
    setDate() {
      this.dateTime = new Date();
    },
  },
  mounted() {
    this.timer = setInterval(() => {
      this.setDate();
    }, 1000);
  },
  beforeUnmount() {
    clearInterval(this.timer);
  },
};
</script>

We have a form that lets the user submit their name.

Inside it, we have an input that binds to the name reactive property with v-model .

The trim modifier lets us trim leading and trailing whitespaces.

The form has the v-if directive to show the form if submitted is false .

And triggering the submit event with the submit button with set submitted to true .

Below that, we should the landing page content by showing the name and dateTime .

In the script tag, we have the data method to return our reactive properties.

The setDate method sets the dateTime to the current date.

The mounted hook calls setInterval to call setDate to update dateTime every second.

The beforeUnmount hook calls clearInterval to clear the timer when we unmount the component.

Conclusion

We can create a landing page with Vue 3 and JavaScript.

Categories
Vue 3 Projects

Create a Drag and Drop App with Vue 3 and JavaScript

Vue 3 is the latest version of the easy to use Vue JavaScript framework that lets us create front end apps.

In this article, we’ll look at how to create a drag and drop app with Vue 3 and JavaScript.

Create the Project

We can create the Vue project with Vue CLI.

To install it, we run:

npm install -g @vue/cli

with NPM or:

yarn global add @vue/cli

with Yarn.

Then we run:

vue create drag-and-drop

and select all the default options to create the project.

Create the Drag and Drop App

To create the drag and drop app, we write:

<template>
  <h2>Draggable Elements</h2>
  <div
    class="draggable"
    :draggable="true"
    @dragstart="drag($event, o)"
    v-for="o of origin"
    :key="o"
    @click.stop
  >
    {{ o }}
  </div>

<h2>Target</h2>
  <div id="target" @dragover.prevent @drop="drop">
    <div class="draggable" v-for="t of target" :key="t">
      {{ t }}
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      origin: ["apple", "orange", "grape"],
      target: [],
    };
  },
  methods: {
    drag(ev, text) {
      ev.dataTransfer.setData("text", text);
    },
    drop(ev) {
      const text = ev.dataTransfer.getData("text");
      const index = this.origin.findIndex((o) => o === text);
      this.origin.splice(index, 1);
      this.target.push(text);
    },
  },
};
</script>

<style scoped>
.draggable {
  border: 1px solid black;
  margin-right: 5px;
}

#target {
  border: 1px solid black;
  width: 95vw;
  height: 100px;
  padding: 5px;
}
</style>

In the template, we have divs under the Draggable Elements heading.

We style the divs by setting the class of each div to draggable .

Then we add a border to the draggable class.

To make the divs draggable, we set the draggable prop to true .

Next, we add the @dragstart directive to listen for the dragstart event, which is triggered when we first start dragging the div.

We use v-for to render the items in the origin array.

And we set the key to the origin entry so that Vue 3 can identify the items.

The entries are unique so we can just assign them as the value of the key prop.

Also, we have the @click.stop directive to stop the propagation of the click event.

Below the Target heading, we have the container div for the draggable items.

We have the @dragover.prevent directive to prevent the default behavior when we drag over the div which lets us keep dragging the item.

The @drop directive lets us call drop to put the items in the target array.

We render the target array inside the div with ID target with v-for .

In the script tag, we have the data method which has the origin and target reactive properties.

The drag method calls ev.dataTransfer.data to set the data we’re transferring when we start dragging the element.

In the drop method, we call ev.dataTransfer.getData to get the data by the key and return the item with key 'text' .

Then we find the item in the origin array and remove it from it with splice .

Then finally, we call this.target.push to append the item to the target array.

The style tag has some styles for the draggable items and the target container div.

Now we can drag the items from the Draggable Elements section to the Target section.

Conclusion

We can add drag and drop features easily into our app with Vue 3 and JavaScript.

Categories
Vue 3 Projects

Create a JSON to CSV Converter with Vue 3 and JavaScript

Vue 3 is the latest version of the easy to use Vue JavaScript framework that lets us create front end apps.

In this article, we’ll look at how to create a JSON to CSV cowith Vue 3 and JavaScript.

Create the Project

We can create the Vue project with Vue CLI.

To install it, we run:

npm install -g @vue/cli

with NPM or:

yarn global add @vue/cli

with Yarn.

Then we run:

vue create json-to-csv

and select all the default options to create the project.

Create the JSON to CSV Converter

To create the JSON to CSV converter, we write:

<template>
  <form @submit.prevent="convert">
    <div>
      <label>json</label>
      <textarea v-model="json"></textarea>
    </div>
    <button type="submit">convert</button>
  </form>
  <div>
    <label>csv</label>
    <textarea v-model="csv"></textarea>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      json: "",
      csv: "",
    };
  },
  methods: {
    convert() {
      const parsedJson = JSON.parse(this.json);
      if (
        !Array.isArray(parsedJson) ||
        !parsedJson.every((p) => typeof p === "object" && p !== null)
      ) {
        return;
      }
      const heading = Object.keys(parsedJson[0]).join(",");
      const body = parsedJson.map((j) => Object.values(j).join(",")).join("n");
      this.csv = `${heading}${body}`;
    },
  },
};
</script>

In the template, we have a form that takes the JSON array string.

The textarea in the form has v-model to bind the inputted value to the json reactive property.

The form element has the @submit directive to listen to the submit event which is triggered when we click convert.

prevent lets us do client-side form submission instead of server-side.

Below that, we have a div to display the CSV result in the textarea.

We bind it to the csv reactive property with v-model .

In the script tag, we have the data method to return the reactive properties.

Then in the convert method, we parse the json string with JSON.parse .

And then we check if the parsed object is an array and that all entries are objects.

Then we create the heading from the keys of the first entry.

We get the keys with Object.keys .

Then we get all the values with Object.values and the join them together with commas with join .

And we join the rows together with join and a new line character as the argument.

Finally, we assign a string with heading and body combined to this.csv to display the result in the 2nd textarea.

Conclusion

We can create a JSON to CSV converter with Vue 3 and JavaScript.