# 前言
在vue3的项目当中,有时候需要使用ref获取到组件的实例对象。当结合 typescript 使用时就需要进行类型的定义才能访问到实例的成员。
就我目前知道的就有三种方式:
- 自定义类型
- 使用InstanceType
- 通过组件的setup函数自动推断
<!-- 组件 child.vue -->
<script lang="ts">
export default defineComponent({
setup() {
const num = ref(0);
return {
num
}
}
})
</script>
<!-- 使用的页面 -->
<template>
<child ref="childRef"/>
</template>
<script lang="ts">
export default defineComponent({
setup() {
const childRef = ref(null);
onMounted(() => {
childRef.value.num; // 如果没有定义类型,这里就无法访问到num
})
}
})
</script>
# 自定义类型
当然 我们也可以直接定义 child.vue 组件实例的类型
直接在 child.vue 中定义类型 ChildCtx
<!-- 组件child.vue -->
<script lang="ts">
// 定义类型
export interface ChildCtx {
num: number;
}
export default defineComponent({
setup() {
const num = ref(0);
return {
num
}
}
})
</script>
在使用的时候
<template>
<child ref="childRef"/>
</template>
<script lang="ts">
import {defineComponent, onMounted} from 'vue';
import {ChildCtx}, Child from './child.vue';
export default defineComponent({
components: {Child},
setup() {
// 定义类型
const childRef = ref<null | ChildCtx>(null);
onMounted(() => {
childRef.value?.num; // 这里可以访问到num属性
})
}
})
</script>
# 使用InstanceType
InstanceType<T>是ts自带的类型,能够直接获取组件完整的实例类型
import Child from './child.vue';
import {ElImage} from 'elment-plus';
type ElImageCtx = InstanceType<typeof ElImage>;
type ChildCtx = InstanceType<type Child>;
//...
setup() {
const child = ref<null | ChildCtx>(null);
const elImgRef = ref<null | ElImagesCtx>(null);
onMounted(() => {
child.value?.num; // 可以直接访问到
elImgRef.value?.// 对于element 组件,可以访问到很多的属性
})
}
# 通过组件的setup函数自动推断
这样做好像不太好。。。只是提供了一种思路,日常使用的话 用 InstanceType<T> 就好了哈。
<template>
<child ref="childRef"/>
</template>
<script>
import {defineComponent, onMounted} from 'vue';
import Child from './child.vue';
// 根据组件自动推断
type ChildCtx = Exclude<ReturnType<Required<typeof Child>['setup']>, void | RenderFunction | Promise<any>>;
export default defineComponent({
components: {Child},
setup(){
//定义类型
const childRef = ref<null | ChildCtx>(null);
onMouned(() => {
childRef.value?.num; // 这里可以访问到 num 属性
})
}
})
</script>