當我們在 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 公開的函數了。
image.png
最后解釋一下代碼邏輯, typeof 是獲取該組件的類型,但是光靠這個關鍵字無法獲取到組件內部的方法的,因為這是基于模板創建的類型而不是組件實例的類型,所以你得通過 InstanceType 來獲取。