What is the recommended data type for the component prop of a Vuelidate field?

I'm currently working on a view that requires validation for certain fields. My main challenge is figuring out how to pass a prop to an InputValidationWrapper Component using something like v$.[keyField], but I'm unsure about the type to set for it.

This issue is in SignInView.vue:

<template>
    <div class="sign-in-view">
        <form @submit.prevent="onSubmit" class="sign-in-form">
            <div class="inputs-container">
                <InputValidationWrapper :validationField="v$.email" required email>
                    <BaseInput title="Email" v-model="formData.email" />
                </InputValidationWrapper>
            </div>
            <button type="submit">submit</button>
        </form>
    </div>
</template>

<script setup lang="ts">
import BaseInput from "@/components/inputs/BaseInput.vue";
import InputValidationWrapper from "@/components/validators/InputValidationWrapper.vue";

import useVuelidate from "@vuelidate/core";
import { required, email } from "@vuelidate/validators";
import { computed, reactive } from "vue";

const formData = reactive({
    email: "",
    password: "",
});

const validationRules = computed(() => {
    return {
        email: { required, email },
        password: { required },
    };
});
const v$ = useVuelidate(validationRules, formData);

const onSubmit = async () => {
    const result = await v$.value.$validate();
    if (!result) return;
    console.log("submit");
};
</script> 

The issue lies within InputValidationWrapper.vue:

<template>
    <div class="input-wrapper">
        <slot />
        <div class="errors-block">
            <RequiredValidation
                :isDirty="validationField.$dirty"
                :isInvalid="validationField.required.$invalid"
                v-if="required" />
            <EmailValidation :isDirty="validationField.$dirty" :isInvalid="validationField.email.$invalid" v-if="email" />
        </div>
    </div>
</template>

<script setup lang="ts">
import RequiredValidation from "./RequiredValidation.vue";
import EmailValidation from "./EmailValidation.vue";
import type { NestedValidations } from "@vuelidate/core/index.js";

type PropsType = {
    validationField: NestedValidations; //???
    required?: boolean;
    email?: boolean;
};

defineProps<PropsType>();
</script>

To address this, I created separate components for each error and passed simple booleans as props. However, I ran into errors with validationField.$dirty causing

Property '$dirty' does not exist on type NestedValidations<ValidationArgs<unknown>, unknown>'.
The same issue occurred with validationField.email.$invalid.

Answer №1

If you want to customize how Vuelidate Validation is passed, you can create your own interface:

For example:

export interface VuelidateValidation {
  $errors: ErrorObject[];
  $error: boolean;
  $invalid: boolean;
  $dirty: boolean;
  $touch: () => void;
}

Then, simply use this interface in your component:

<script setup lang="ts">
export interface Props {
  validation?: VuelidateValidation
}
const props = defineProps<Props>();
const model = defineModel();
</script>
<template>
  <input type="text" v-model="model" @input="validation?.$touch" @blur="validation?.$touch" />
  <div v-if="validation?.$error">
    Oops, something went wrong.
  </div>
</template>

When using this component, you can easily pass your custom Vuelidate validation property:

<template>
  <MyComponent :validation="v$.email" />
</template>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

How can I showcase array elements using checkboxes in an Ionic framework?

Having a simple issue where I am fetching data from firebase into an array list and need to display it with checkboxes. Can you assist me in this? The 'tasks' array fetched from firebase is available, just looking to show it within checkboxes. Th ...

Create a d.ts file for Vue components that are written using Typescript

As a newcomer to Vue, I am eager to dive into creating components and publishing packages to NPM. My plan is to develop Vue (typescript) + Vuetify reusable components that can be easily installed from NPM into any of my projects. While I have successfully ...

Embed Vue applications within the container of the main Vue application

My goal is to establish a foundational Vue application that offers essential features such as signing in, navigating with a sidebar, and the flexibility to interchange navbar items. I envision creating separate Vue applications for each navbar item. Main ...

Troubleshooting webpack encore issues with importing enums from node_modules

I am faced with a challenge of utilizing an enum from a library I created in a different project. The library is developed using Vue and typescript, bundled with rollup. On the other hand, the project is built with Symfony, with the front end also using Vu ...

Is it possible to deduce Typescript argument types for a specific implementation that has multiple overloaded signatures?

My call method has two signatures and a single implementation: call<T extends CallChannel, TArgs extends CallParameters[T]>(channel: T, ...args: TArgs): ReturnType<CallListener<T>>; call<T extends SharedChannel, TArgs extends SharedPar ...

Tips for saving an image link when displaying an image in VueJS using the 'require' method

I am currently working on a project that involves displaying Pizza items with their respective images. Each Pizza object is stored in the database along with an imgUrl field. Strangely, the images are not showing up on the page, although I can see the alt ...

Is it possible to assign a variable in typescript using the interface as its type?

Here's the snippet of code I have written interface apiResult { Token: string; Result: any; } const result: apiResult = payload.Result; I am wondering about the significance of this code. Is it possible to assign a type from an interface to ...

Understanding how to infer literal types or strings in Typescript is essential for maximizing the

Currently, my goal is to retrieve an object based on the parameter being passed in. I came across a similar question that almost meets my requirements. TypeScript function return type based on input parameter However, I want to enhance the function's ...

Creating number inputs in Ionic 2/3 using alerts

I am currently working with Ionic 3.x on my macOS system. The issue I am facing is as follows: I have an array that contains a number and another array consisting of names. table: { number: number, names: string[] } = { number: 0, names: ['& ...

Leveraging the find method to sort through an array with dual parameters

I'm facing an issue while trying to filter my array of objects using two parameters. Despite having an object in the array with the same values as the parameters, the result is empty. const item = this.lista.find(i => i.number === rule.number && ...

Using ReactJS with Material UI and applying styles with withStyles including themes in TypeScript

I've been working on converting the Material UI Dashboard into TypeScript. You can find the original code here: Material UI Dashboard One issue I'm encountering is that I am unable to define CSS styles within the withStyles function while export ...

Ways to call a method in a grandparent from a grandchild

I am stuck on what to name this particular scenario. I have a file, which we'll refer to as parent.vue. It contains the following: PARENT.vue <template> <input-box :room="currentRoom" v-on:messagesent="getMessages&qu ...

Angular 6 issue: Data not found in MatTableDataSource

Working on implementing the MatTableDataSource to utilize the full functionality of the Material Data-Table, but encountering issues. Data is fetched from an API, stored in an object, and then used to create a new MatTableDataSource. However, no data is b ...

Error encountered while trying to install vue-apollo on a Vue 3.0 application due to version discrepancies

I created a fresh Vue 3.0 application by running vue create Next, I integrated apollo into my project using vue add apollo However, upon executing npm run build, an error occurred: ERROR Failed to compile with 2 errors ...

What is the best way to outline this model using typescript?

Here is a JSON model that I am working with: { "loggers" : { "logger1" : { "name" : "logger1", "level" : "DEBUG", "sub_loggers" :{ "logger1.nested_logger1" : { "name": "lo ...

"Looking to log in with NextAuth's Google Login but can't find the Client Secret

I am attempting to create a login feature using Next Auth. All the necessary access data has been provided in a .env.local file. Below are the details: GOOGLE_CLIENT_ID=[this information should remain private].apps.googleusercontent.com GOOGLE_CLIENT_SECR ...

Utilizing lodash and Angular 8: Identifying an valid array index then verifying with an if statement

In my current project, I am developing an e-commerce angular application that includes a basket with two types of products: restaurant + show combos and gift cards. When a client reserves a restaurant, they must also reserve a show; conversely, the client ...

There were issues with React's compilation when integrating with antd UI

Whenever I try to compile, errors keep showing up even though I have imported from antd. I can't figure out what the problem is. These are the errors I encounter while compiling: Compiled with problems: ERROR in ./src/components/excelPage.js 130:85- ...

Tips for evaluating the stickiness of a block within a cell when it adheres to a mat-header-cell

I am working with an Angular table and facing an issue. How can I make the span element in the cells of the first column stick to the sticky mat-header-row when scrolling down the table? My requirement is for the span element to stay attached to the lower ...

Preventing Firebase duplicates leads to the error of not being able to read the property 'apps'

Struggling to incorporate Firebase into a TypeScript/NextJS project, I have encountered difficulties. Despite successfully importing and initializing the app: import * as firebase from "firebase/app"; import { collection, getDocs } from "fir ...