当我们在 Vue 项目里获取组件的实例时,一般都是在 <template>
模板直接 ref="your name",这种方式实际也是调用 document.getElementXXX ,但是在 TS 语言下有一个问题,我们该如何定义这个类型,一般情况下开发工具无法正确提示该组件的方法,但是我们可以通过正确的类型标注来辅助 TS 进行类型推断。
子组件 CheckBox.vue
<script setup lang="ts">
import cbChecked from '~/assets/images/cb-checked.png'
import cbUnchecked from '~/assets/images/cb-unchecked.png'
const props = withDefaults(
defineProps<{
isChecked?: boolean
}>(),
{
isChecked: false,
},
)
const emits = defineEmits(['update:isChecked'])
const localStatus = useVModel(props, 'isChecked', emits)
const println = (msg: string) => {
console.log(`父组件调用 msg=${msg}`)
}
function printlnTest() {
console.log('父组件调用 printlnTest')
}
defineExpose({
printlnTest,
println,
})
</script>
<template>
<img
class="w-0.48rem h-0.48rem"
:aria-checked="localStatus"
:src="localStatus ? cbChecked : cbUnchecked"
alt="checkbox" @click="localStatus = !localStatus"
>
</template>
父组件
import CheckBox from '@/xxx/components/CheckBox.vue'
import type CheckBoxType from '@/xxx/components/CheckBox.vue'
const checkbox = ref<InstanceType<typeof CheckBoxType> | null>()
<template>
<CheckBox
ref="checkbox"
v-model:is-checked="introducePage.checkBoxStatus"
/>
</template>
这个时候,当我们输入checkbox.value?. 时,编译器就会自动提示可以调用 defineExpose 公开的函数了。
最后解释一下代码逻辑, typeof 是获取该组件的类型,但是光靠这个关键字无法获取到组件内部的方法的,因为这是基于模板创建的类型而不是组件实例的类型,所以你得通过 InstanceType 来获取。