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

Ric*_*ick 13 javascript typescript vue.js vue-component vuejs2

用打字稿重写VueJs项目时,遇到了TypeScript错误。

这是具有自定义v模型的组件的一部分。

html中的输入字段具有一个称为“ plate”的引用,我想访问该值。该字段上的@input调用下面编写的update方法。

打字稿抱怨板上没有价值。

@Prop() value: any;

update() {
    this.$emit('input',
        plate: this.$refs.plate.value
    });
}
Run Code Online (Sandbox Code Playgroud)

模板:

<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>
Run Code Online (Sandbox Code Playgroud)

Joh*_*now 32

编辑 - 2021-03(组合 API)

更新此答案是因为 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>
Run Code Online (Sandbox Code Playgroud)

编辑 - 2020-04:

vue-property-decorator库提供了我推荐的@Ref而不是我的原始答案。

<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>
Run Code Online (Sandbox Code Playgroud)

原答案

以上答案都不适用于我想要做的事情。添加以下 $refs 属性结束修复它并似乎恢复了预期的属性。我在这个 github 帖子上找到了链接的解决方案

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
}
Run Code Online (Sandbox Code Playgroud)


Geo*_*rge 15

你可以这样做:

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

  someMethod () {
    this.$refs.checkboxElement.checked
  }
}
Run Code Online (Sandbox Code Playgroud)

从此问题开始:https : //github.com/vuejs/vue-class-component/issues/94

  • 我正在使用 ```let mycomp = Vue.extend({})``` 语法。我怎么能在这方面做同样的事情?我还应该使用上述语法吗? (10认同)
  • 我需要编写 `$refs!:` (注意感叹号)才能使其工作,但我使用的是 `vue-property-decorator`。@George 如果我的修复没问题,您可以编辑答案吗?不想为类组件用户破坏它,因为可能存在一些差异(编辑:实际上感叹号位于您发布的链接中) (4认同)

小智 8

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

  • 这清除了错误,但首先就抵消了使用打字稿的好处。 (4认同)
  • 应该是 `(this.$refs['refField'] as any).value` (3认同)

DrS*_*sor 6

避免使用括号< >进行类型转换,因为它会与 JSX 冲突。

试试这个

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

作为我一直牢记的笔记

Typescript 只是具有强大打字能力的 Javascript,以确保类型安全。因此(通常)它不会预测 X 的类型(var、param 等),也不会自动对任何操作进行类型转换。

此外,打字稿的另一个目的是使 JS 代码变得更清晰/可读,因此尽可能定义类型。


bes*_*ton 5

儿子.vue

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

父.vue

<son ref="son" />

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

//use
this.son.help();
Run Code Online (Sandbox Code Playgroud)

  • 引用自定义组件类型的绝佳方式。这种方式还允许我避免使用类装饰器。 (2认同)