说明

当我们在使用组件时,经常需要获取组件的实例,以便调用组件暴露出来的方法。在Vue3中,我们可以使用ref来获取组件的实例,但是我们需要手动指定组件的类型。为了简化这个过程,我们可以封装一个函数来提供组件实例的类型。提供以下两种方式,一种只能用于非泛型组件,一种是两种都能使用。

注意:当组件是泛型组件也就是添加了generic="T"时,则只能使用useComponentRef<T>()

  1. useComponentRef(T)
    ✅️非泛型组件
    ⬜️泛型组件
  2. useComponentRef<T>()
    ✅️非泛型组件
    ✅️泛型组件

非泛型组件-useComponentRef(T)

定义

1
2
3
export function useComponentRef<T extends abstract new (...args: any) => any>(_component: T) {
return ref<InstanceType<T>>()
}

使用

1
2
3
4
5
6
7
8
9
10
<script setup lang="ts">
import { defineComponent, ref } from 'vue'
import MyComponent from '@/components/MyComponent.vue'
import { useComponentRef } from './useComponentRef'

//使用
const instance = useComponentRef(MyComponent)
instance.value.myMethod()

</script>

泛型组件-useComponentRef<T>()

定义

  1. 自定义类型ComponentInstance
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//定义类型
type ComponentInstance<T> = T extends new (...args: any[]) => infer R
? R
: T extends (...args: any[]) => infer R
? R extends { __ctx?: infer K }
? Exclude<K, void> extends { expose: (...args: infer K) => void }
? K[0] & InstanceType<DefineComponent>
: any
: any
: any

//定义useComponentRef方法,和第一种不同的是,这里需要传入泛型参数
export function useComponentRef<T>() {
return ref<ComponentInstance<T>>()
}
  1. ✨使用vue-component-type-helpers
1
2
3
4
5
6
import { ComponentInstance } from 'vue-component-type-helpers'

//定义useComponentRef方法,和第一种不同的是,这里需要传入泛型参数
export function useComponentRef<T>() {
return ref<ComponentExposed<T>>()
}

使用

1
2
3
4
5
6
7
8
9
10
<script setup lang="ts">
import { defineComponent, ref } from 'vue'
import MyComponent from '@/components/MyComponent.vue'
import { useComponentRef } from './useComponentRef'

//使用
const instance = useComponentRef<typeof MyComponent>()
instance.value.myMethod()

</script>