[英]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
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>
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
}
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.