Issue
I created v-form
like this
<v-form ref="form" v-model="valid" lazy-validation>
<!-- form content -->
<v-btn
:disabled="!valid"
@click="submit"
>
Submit
</v-btn>
</v-form>
script:
if (this.$refs.form.validate()) // Error is in here
If i just console.log(this.$ref.form)
the validate() function is available. But why this error is coming while building?
Solution
Solutions:
Simple:
(this.$refs.form as Vue & { validate: () => boolean }).validate()
Alternative (use this if you reference this.$refs.form
multiple times in your component):
computed: {
form(): Vue & { validate: () => boolean } {
return this.$refs.form as Vue & { validate: () => boolean }
}
} // Use it like so: this.form.validate()
Reusable (use this if you use the v-form
component multiple times across your application):
// In a TS file
export type VForm = Vue & { validate: () => boolean }
// In component, import `VForm`
computed: {
form(): VForm {
return this.$refs.form as VForm
}
}
Explanation:
In the Vue
template syntax, we can use the ref
attribute on a Vue
instance or a DOM element. If ref
is used in a v-for
loop, an array of Vue
instances or DOM elements is retreived.
This is why this.$refs
can either return Vue | Element | Vue[] | Element[]
.
In order for TypeScript
to know which type is being used, we need to cast the value.
We can either do:
(this.$refs.form as Vue).validate()
or (<Vue>this.$refs.form).validate()
We cast it to Vue
because v-form
is a Vue
instance (component) and not an Element
.
My personal preference is to create a computed property which returns the Vue
instance(s) or DOM element(s) already casted.
ie.
computed: {
form(): Vue {
return this.$refs.form as Vue
}
}
The v-form
instance has a validate
method that returns a boolean, so we need to use an intersection type literal:
computed: {
form(): Vue & { validate: () => boolean } {
return this.$refs.form as Vue & { validate: () => boolean }
}
}
Then we can use it like so: this.form.validate()
A better solution would be to create a type with the intersection so that it can be reused across multiple components.
export type VForm = Vue & { validate: () => boolean }
Then import it in the component:
computed: {
form(): VForm {
return this.$refs.form as VForm
}
}
Answered By - Ricky Ruiz
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.