web-dev-qa-db-fra.com

Type de script dans vue - La propriété 'validate' n'existe pas sur le type 'Vue | Element | Vue [] | Element []'.

J'ai créé v-form Comme ceci

<v-form ref="form" v-model="valid" lazy-validation>
  ...
  <v-btn
     :disabled="!valid"
     @click="submit"
   >
     submit
   </v-btn>
</v-form>

scénario:

if (this.$refs.form.validate()) // Error is in here

Si je viens de console.log(this.$ref.form) la fonction validate () est disponible. Mais pourquoi cette erreur survient lors de la construction?

9
Sam

Solutions:

Simple:

(this.$refs.form as Vue & { validate: () => boolean }).validate()

Alternative (utilisez-la si vous faites référence à this.$refs.form Plusieurs fois dans votre composant):

computed: {
  form(): Vue & { validate: () => boolean } {
    return this.$refs.form as Vue & { validate: () => boolean }
  }
} // Use it like so: this.form.validate()

Réutilisable (utilisez ceci si vous utilisez le composant v-form Plusieurs fois dans votre application):

// In a TS file
export type VForm = Vue & { validate: () => boolean }

// In component, import `VForm`
computed: {
  form(): VForm {
    return this.$refs.form as VForm
  }
}

Explication:

Dans la syntaxe du modèle Vue, nous pouvons utiliser l'attribut ref sur une instance Vue ou un élément DOM. Si ref est utilisé dans une boucle v-for, Un tableau d'instances Vue ou d'éléments DOM est récupéré.

C'est pourquoi this.$refs Peut retourner Vue | Element | Vue[] | Element[].

Afin que TypeScript sache quel type est utilisé, nous devons convertir la valeur.

On peut soit faire:

(this.$refs.form as Vue).validate() Ou (<Vue>this.$refs.form).validate()

Nous le convertissons en Vue car v-form Est une instance de Vue (composant) et non une Element.

Ma préférence personnelle est de créer une propriété calculée qui renvoie les instances Vue ou les éléments DOM déjà castés.

c'est à dire.

computed: {
  form(): Vue {
    return this.$refs.form as Vue
  }
}

L'instance v-form A une méthode validate qui renvoie un booléen, nous devons donc utiliser un littéral de type intersection:

computed: {
  form(): Vue & { validate: () => boolean } {
    return this.$refs.form as Vue & { validate: () => boolean }
  }
}

Ensuite, nous pouvons l'utiliser comme ceci: this.form.validate()


Une meilleure solution serait de créer un type avec l'intersection afin qu'il puisse être réutilisé sur plusieurs composants.

export type VForm = Vue & { validate: () => boolean }

Importez-le ensuite dans le composant:

computed: {
  form(): VForm {
    return this.$refs.form as VForm
  }
}
20
Ricky
let form: any = this.$refs.form
if(form.validate){}
3
wuyuchao

Impossible de commenter la solution acceptée car je suis nouveau sur StackOverflow et je voulais fournir ma solution à cela. J'ai pris la même étape initiale pour enquêter que OP et j'ai fait une console.log(this.$ref.form), la sortie sur la console est en fait un tableau de [VueComponent] et validate() la fonction n'existe pas dans ce contexte .

J'ai pu accéder à la fonction validate() sur le formulaire en faisant this.$ref.form[0].validate()

0
Ralph Gliane