【问题标题】:Typescript in vue - Property 'validate' does not exist on type 'Vue | Element | Vue[] | Element[]'.vue 中的打字稿-“Vue | 类型”上不存在属性“验证”元素 | Vue[] |元素[]'。
【发布时间】:2019-02-06 03:11:50
【问题描述】:

我这样创建了v-form

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

脚本:

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

如果我只是console.log(this.$ref.form) validate() 函数可用。但是为什么在构建时会出现这个错误?

【问题讨论】:

    标签: typescript vue.js vuetify.js


    【解决方案1】:

    解决方案:

    简单:

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

    替代(如果您在组件中多次引用this.$refs.form,请使用此选项)

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

    可重用(如果您在应用程序中多次使用v-form 组件,请使用它)

    // In a TS file
    export type VForm = Vue & { validate: () => boolean }
    
    // In component, import `VForm`
    computed: {
      form(): VForm {
        return this.$refs.form as VForm
      }
    }
    

    解释:

    Vue 模板语法中,我们可以在Vue 实例或DOM 元素上使用ref 属性。如果在v-for 循环中使用ref,则会检索Vue 实例或DOM 元素的数组。

    这就是为什么this.$refs 可以返回Vue | Element | Vue[] | Element[]

    为了让TypeScript 知道正在使用哪种类型,我们需要转换值。

    我们可以这样做:

    (this.$refs.form as Vue).validate()(&lt;Vue&gt;this.$refs.form).validate()

    我们将其转换为Vue,因为v-formVue 实例(组件)而不是Element

    我个人的偏好是创建一个计算属性,该属性返回已转换的 Vue 实例或 DOM 元素。

    即。

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

    v-form 实例有一个返回布尔值的validate 方法,因此我们需要使用交集类型文字:

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

    那么我们可以这样使用它:this.form.validate()


    更好的解决方案是创建一个具有交集的类型,以便可以跨多个组件重用它。

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

    然后在组件中导入:

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

    【讨论】:

    • 这仍然抛出错误,我不知道为什么。但如果我使用 (this.$refs.form as any).validate() 。如果我给 Vue 作为类型它不起作用,但用 any 替换是有效的。为什么会这样?
    • 问题是Vue接口没有validate方法。该方法仅在 v-form vue 实例中声明。我不知道 vuetify 推荐什么或者他们是否有类型,基本上应该有一个扩展 Vue 实例的V-Form 接口,让TypeScript 知道该特定组件中存在哪些方法。
    • @Sam 另一种方法是您执行以下操作:(this.$refs.form as Vue &amp; { validate: () =&gt; boolean }).validate()
    • 谢谢你,它有效。你能解释一下这个(this.$refs.form as Vue &amp; { validate: () =&gt; boolean }).validate()。它是如何工作的?
    • 最好的方法是什么? (this.$refs.form as any).validate()(this.$refs.form as Vue &amp; { validate: () =&gt; boolean }).validate()
    【解决方案2】:

    如果您将vue-class-componentvue-property-decorator 一起使用,您可以这样做:

    types.ts 中定义一个带有 vuetify 表单函数的新类型:

    export type VForm = Vue & {
      validate: () => boolean;
      resetValidation: () => boolean;
      reset: () => void;
    };
    

    然后导入你的组件:

    import { VForm } from "types";
    import { Component, Ref} from "vue-property-decorator";
    

    在你的组件中使用@Ref 来定义表单:

    export default class YourComponent extends Vue {
      @Ref("form") readonly form!: VForm;
    }
    

    所以在你的方法中你可以像这样使用它:

    this.form.validate();
    this.form.resetValidation();
    this.form.reset();
    

    【讨论】:

    • 这比我给你的 +1 更值得!!
    • 很高兴听到它对您有所帮助!如果你愿意,请随时给我一些咖啡;)ko-fi.com/gander
    【解决方案3】:
    let form: any = this.$refs.form
    if(form.validate){}
    

    【讨论】:

    • 虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
    • 恐怕这也是一个糟糕的建议。这只是禁用类型检查...这是 TypeScript 的重点。
    【解决方案4】:

    没有一个答案做到了。我试图让验证然后承诺在表单上工作。

    根据comment

    如果你正在使用打字稿构建你的 vue 组件

    export default Vue.extend({})
    

    然后做

    import { ValidationObserver, ValidationProvider, extend } from "vee-validate";
    import { required } from "vee-validate/dist/rules";
    import Vue, { VueConstructor } from "vue";
    export default (Vue as VueConstructor<
      Vue & {
        $refs: {
          form: InstanceType<typeof ValidationProvider>;
        };
      }
    >).extend({
      methods: {
        saveEntity() {
          if (this.loading) return;
          console.log(this.entity);
          this.$refs.form.validate().then(success => {
            if (!success) {
              console.log("not valid");
              return;
            }
            console.log("valid");
          });
        }
      }
    })
    

    这验证了 ValidationObserver ref="form" 就好了。

    【讨论】:

      【解决方案5】:

      由于我是 StackOverflow 的新手并想为此提供我的解决方案,因此无法对已接受的解决方案发表评论。我采取与 OP 相同的初始步骤进行调查并执行了 console.log(this.$ref.form),控制台上的输出实际上是 [VueComponent] 数组,而 validate() 函数在该上下文中不存在。

      我可以通过 this.$ref.form[0].validate() 访问表单上的 validate() 函数

      【讨论】:

        猜你喜欢
        • 2021-08-21
        • 2017-08-07
        • 2019-07-16
        • 2019-03-07
        • 2016-08-15
        • 2017-11-09
        • 2018-07-23
        • 2022-01-07
        • 2020-12-18
        相关资源
        最近更新 更多