简体   繁体   English

Vuejs 打字稿 this.$refs。<refField> .value 不存在

[英]Vuejs typescript this.$refs.<refField>.value does not exist

While rewriting my VueJs project in typescript, I came across a TypeScript error.在使用 typescript 重写我的 VueJs 项目时,我遇到了一个 TypeScript 错误。

This is a part of the component that has a custom v-model.这是具有自定义 v-model 的组件的一部分。

An input field in the html has a ref called 'plate' and I want to access the value of that. html 中的输入字段有一个名为“plate”的引用,我想访问它的值。 The @input on that field calls the update method written below.该字段上的@input 调用下面编写的更新方法。

Typescript is complaining that value does not exist on plate.打字稿抱怨盘子上不存在价值。

@Prop() value: any;

update() {
    this.$emit('input',
        plate: this.$refs.plate.value
    });
}

template:模板:

<template>  
<div>
    <div class="form-group">
        <label for="inputPlate" class="col-sm-2 control-label">Plate</label>

        <div class="col-sm-10">
            <input type="text" class="form-control" id="inputPlate" ref="plate" :value="value.plate" @input="update">
        </div>
    </div>

</div>
</template>

You can do this:你可以这样做:

class YourComponent extends Vue {
  $refs!: {
    checkboxElement: HTMLFormElement
  }

  someMethod () {
    this.$refs.checkboxElement.checked
  }
}

From this issue: https://github.com/vuejs/vue-class-component/issues/94从这个问题: https : //github.com/vuejs/vue-class-component/issues/94

Edit - 2021-03 (Composition API)编辑 - 2021-03(组合 API)

Updating this answer because Vue 3 (or the composition API plugin if you're using Vue 2) has some new functions.更新此答案是因为 Vue 3(或组合 API 插件,如果您使用的是 Vue 2)具有一些新功能。

<template>
  <div ref="root">This is a root element</div>
</template>

<script lang="ts">
  import { ref, onMounted, defineComponent } from '@vue/composition-api'

  export default defineComponent({
    setup() {
      const root = ref(null)

      onMounted(() => {
        // the DOM element will be assigned to the ref after initial render
        console.log(root.value) // <div>This is a root element</div>
      })

      return {
        root
      }
    }
  })
</script>

Edit - 2020-04:编辑 - 2020-04:

The vue-property-decorator library provides @Ref which I recommend instead of my original answer. vue-property-decorator库提供了我推荐的@Ref而不是我原来的答案。

import { Vue, Component, Ref } from 'vue-property-decorator'

import AnotherComponent from '@/path/to/another-component.vue'

@Component
export default class YourComponent extends Vue {
  @Ref() readonly anotherComponent!: AnotherComponent
  @Ref('aButton') readonly button!: HTMLButtonElement
}

Original Answer原答案

None of the above answers worked for what I was trying to do.以上答案都不适用于我想要做的事情。 Adding the following $refs property wound up fixing it and seemed to restore the expected properties.添加以下 $refs 属性结束修复它并似乎恢复了预期的属性。 I found the solution linked on this github post.我在这个 github 帖子上找到了链接的解决方案

class YourComponent extends Vue {
  $refs!: {
    vue: Vue,
    element: HTMLInputElement,
    vues: Vue[],
    elements: HTMLInputElement[]
  }

  someMethod () {
    this.$refs.<element>.<attribute>
  }
}

这对我有用:使用(this.$refs.<refField> as any).value(this.$refs.['refField'] as any).value

son.vue儿子.vue

const Son = Vue.extend({
  components: {},
  props: {},
  methods: {
    help(){}
  }
  ...
})
export type SonRef = InstanceType<typeof Son>;
export default Son;

parent.vue父.vue

<son ref="son" />

computed: {
  son(): SonRef {
    return this.$refs.son as SonRef;
  }
}

//use
this.son.help();

Avoid using bracket < > to typecast because it will conflict with JSX.避免使用括号< >进行类型转换,因为它会与 JSX 冲突。

Try this instead试试这个

update() {
    const plateElement = this.$refs.plate as HTMLInputElement
    this.$emit('input', { plate: plateElement.value });
}

as a note that I always keep remembering作为我一直记得的笔记

Typescript is just Javascript with strong typing capability to ensure type safety. Typescript 只是具有强大类型功能以确保类型安全的 Javascript。 So (usually) it doesn't predict the type of X (var, param, etc) neither automatically typecasted any operation.因此(通常)它不会预测 X 的类型(var、param 等),也不会自动对任何操作进行类型转换。

Also, another purpose of the typescript is to make JS code became clearer/readable, so always define the type whenever is possible.此外,打字稿的另一个目的是使 JS 代码变得更清晰/可读,所以总是尽可能定义类型。

Maybe it will be useful to someone.也许它会对某人有用。 It looks more beautiful and remains type support.它看起来更漂亮,并保持类型支持。

HTML: HTML:

<input ref="inputComment" v-model="inputComment">

TS: TS:

const inputValue = ((this.$refs.inputComment as Vue).$el as HTMLInputElement).value;

In case of custom component method call,在自定义组件方法调用的情况下,

we can typecast that component name, so it's easy to refer to that method.我们可以对该组件名称进行类型转换,因此很容易引用该方法。

eg例如

(this.$refs.annotator as AnnotatorComponent).saveObjects();

where AnnotatorComponent is class based vue component as below.其中 AnnotatorComponent 是基于类的 vue 组件,如下所示。

@Component
export default class AnnotatorComponent extends Vue {
    public saveObjects() {
        // Custom code
    }
}

I found a way to make it work but it is ugly in my opinion.我找到了一种使它工作的方法,但在我看来它很丑陋。

Feel free to give other/better suggestions.随意提供其他/更好的建议。

update() {
    this.$emit('input', {
        plate: (<any>this.$refs.plate).value,
    });
}

Make sure to wrap your exports with Vue.extend() if you are converting your existing vue project from js to ts and want to keep the old format.如果您要将现有的vue项目从 js 转换为 ts 并希望保留旧格式,请确保使用Vue.extend()包装您的导出。

Before:前:

在此处输入图片说明

<script lang="ts">

export default {
  mounted() {
    let element = this.$refs.graph;

...

After:后:

在此处输入图片说明

<script lang="ts">

import Vue from "vue";

export default Vue.extend({
  mounted() {
    let element = this.$refs.graph;

...

With Vue 3 and the Options API, this is what worked for me:使用 Vue 3 和 Options API,这对我有用:

<script lang="ts">
import {defineComponent} from 'vue';

export default defineComponent({
  methods: {
    someAction() {
      (this.$refs.foo as HTMLInputElement).value = 'abc';
    },
  },
});
</script>

The autocomplete doesn't bring the foo property from $refs because it's defined in the template, and apparently there's no information inferred from it.自动完成不会从$refs中带来foo属性,因为它是在模板中定义的,显然没有从中推断出任何信息。

However, once you force the casting of .foo to the HTML element type, everything works from there on, so you can access any element property (like .value , in the example above).但是,一旦您强制将.foo强制转换为 HTML 元素类型,一切都将从那里开始,因此您可以访问任何元素属性(如.value ,在上面的示例中)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 vuejs this.$refs 用于多个元素 - vuejs this.$refs for more than one element VueJS:@keydown、@keyup 和 this.$refs 适用于输入,但不适用于 md-textarea - VueJS: @keydown, @keyup, and this.$refs works with input, but not with md-textarea Vuejs 在方法中获取 $refs 值 - Vuejs get $refs value in methods 在通过调用 this.$refs 更改 vuejs 的 html 标题后,vuejs 之后不会更新该 html 元素 - after changing vuejs's html heading by calling this.$refs, vuejs not updating that html element afterwards Vue this.$refs 返回一个 object 看起来为空但在检查器中有值 - Vue this.$refs returns an object that looks empty but has the value in the inspector 为什么 this.$refs.inuputField&#39;.focus() 在 Vue 中不起作用? - Why does this.$refs.inuputField'.focus() not work in Vue? 类型错误:this.$refs 不是 function - TypeError: this.$refs is not a function 引用数组 typescript 错误:属性“getBoundingClientRect”在类型“RefObject”上不存在<htmlelement> '</htmlelement> - Array of refs typescript error: Property 'getBoundingClientRect' does not exist on type 'RefObject<HTMLElement>' 错误:Function 组件不能有参考。? - Error : Function components cannot have refs.? Typescript 联合:类型“””上不存在属性“值” - Typescript Union: Property 'value' does not exist on type '“”'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM