前言:
在日常开发中,我们通过ref获取组件实例,从而执行其内部的方法,这样的操作很常见。但是其获取的实例我们无法确定其类型,本文围绕这个主题展开讲一下,高手请略过。
通过阅读本文,可以学习到如下知识点:
- Vue内置类型InstanceType
- useTemplateRef
示例:
子组件如下:
// Comp.vue
<template>
count:{{countRef}}
<button @click="add">+</button>
</template>
<script lang="ts" setup>
import {ref} from "vue";
const countRef = ref(0);
function add(){
countRef.value ++;
}
defineExpose({add});
</script>
当我们在父组件使用的时候,想要执行其内部的方法
// Index.vue中
<template>
<Comp ref="compRef"></Comp>
<button @click="handleClick">click me!</button>
</template>
<script setup lang="ts">
import { ref} from 'vue';
import Comp from './Comp.vue';
const compRef = ref(null);
function handleClick(){
compRef.value.handleAdd();
}
</script>
但是,此时compRef的类型是any,我们根本不知道当前获取的组件实例上有什么方法。
我们可以通过Vue中内置的类型InstanceType进行标注,从而获得类型提示。我们将代码按照如下修改:
<script setup lang="ts">
import { Ref, ref} from 'vue';
import Comp from './components/Comp.vue';
type compType = InstanceType<typeof Comp>;
const compRef:Ref<compType|null> = ref(null);
function handleClick(){
compRef.value?.handleAdd();
}
</script>
注意:如果你的子组件是使用setup实现的,那么一定要定义defineExpose进行导出, 但是尽管现在类型已经支持,但是vue注册模版通过定义一个变量,就能与组件实例绑定的这种操作,在网上也是备受争议,所以在vue3.5以后的版本里面给我们提供了一个新的API:useTemplateRef,使其操作更符合正常的思维逻辑,不再那么突兀。
<script setup lang="ts">
import { useTemplateRef } from 'vue';
import Comp from './components/Comp.vue';
type compType = InstanceType<typeof Comp>;
const compRef = useTemplateRef<compType>("compRef");
function handleClick(){
compRef.value?.handleAdd();
}
</script>