Look, I have a view where I need to validate some fields. The main problem is that I want to pass prop to a InputValidationWrapper Component like v$.[keyField]
. But I don't know what type to set.
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>
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>
As you can see I make new component for each error and pass a props there as simple boolean. But validationField.$dirty
throws an error Property '$dirty' does not exist on type NestedValidations<ValidationArgs<unknown>, unknown>'.
and the same thing with validationField.email.$invalid
You can define your own interface to pass the Vuelidate Validation:
i.e.
export interface VuelidateValidation {
$errors: ErrorObject[];
$error: boolean;
$invalid: boolean;
$dirty: boolean;
$touch: () => void;
}
And then you just use that 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">
Something wrong here.
</div>
</template>
When you use that component you can just pass your vuelidate validation property:
<template>
<MyComponent :validation="v$.email" />
</template>