vue中的打字稿-类型'Vue |中没有属性'validate'元素| Vue [] |元件[]'。

时间:2018-08-31 06:13:30

标签: typescript vue.js vuetify.js

我这样创建了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()函数可用。但是,为什么在构建时会出现此错误?

6 个答案:

答案 0 :(得分:11)

解决方案:

简单:

(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模板语法中,我们可以在ref实例或DOM元素上使用Vue属性。如果在ref循环中使用v-for,则会获取Vue实例或DOM元素的数组。

这就是this.$refs可以返回Vue | Element | Vue[] | Element[]的原因。

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

我们可以这样做:

(this.$refs.form as Vue).validate()(<Vue>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
  }
}

答案 1 :(得分:2)

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

types.ts中使用vuetify表单函数定义一个新的Type:

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();

答案 2 :(得分:1)

let form: any = this.$refs.form
if(form.validate){}

答案 3 :(得分:0)

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

我可以通过执行validate()

来访问表单上的this.$ref.form[0].validate()函数

答案 4 :(得分:0)

没有答案。我试图获得验证,然后保证可以在表单上工作。

根据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 :(得分:-1)

如果您使用的是 Typescript,请不要创建新的 Type 和伪造的方法名称。只需调用原始类型即可。

enter image description here

我们可以看到Form的类型是“HTMLFormElement”。 所以要让所有方法都显示在代码上是完整的:

enter image description here

然后,如果你在多个地方使用它,我确实会像@Ricky 建议的那样在 Computed 方法上使用它。

或者像这样简单地投射和使用它

enter image description here