在 vue3 的项目当中,有时候需要使用 ref 获取到组件的实例对象。 当结合 typescript 使用时就需要进行类型的定义才能访问到实例的成员。

就我目前知道的就有三种方式

  • 自定义类型
  • 使用 InstanceType
  • 通过组件的setup函数自动推断
  • // 组件 child.vue
    <script lang="ts">
      export default defineComponent({
      setup(){
         const num  = ref(0);
         return {
    </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 {
    </script>
    

    在使用的时候

     <template>
       <child ref="childRef"/>
     </template>
      import {defineComponent, onMouned } from 'vue'
      import {ChildCtx}, Child from './child.vue'
      <script lang="ts">
         export default   defineComponent({
            components: {Child},
            setup(){
             //++ 定义类型
             const childRef = ref<null | ChildCtx>(null);
             onMouned(() => {
                childRef.value?.num; // 这里可以访问到 num 属性
      </script>
    

    使用 InstanceType

    InstanceType<T> 是 ts 自带的类型, 能够直接获取组件完整的实例类型

      import Child from './child.vue'
      import {ElImage} from 'element-plus'
      type ElImageCtx = InstanceType<typeof ElImage>;
      type ChildCtx = InstanceType<typeof Child>;
      setup() {
         const child = ref<null | ChildCtx>(null);
         const elImgRef = ref<null | ElImageCtx>(null)
         onMounted(() => {
           child.value?.num ;// 可以直接访问到
           elImgRef.value?. // 对于 element组件,可以访问到很多的属性
    

    通过组件的setup函数自动推断

    这样做好像不太好。。。只是提供了一种思路,日常使用的话 用 InstanceType<T> 就好了哈。

     <template>
       <child ref="childRef"/>
     </template>
      import {defineComponent, onMouned } from 'vue'
      import  Child from './child.vue'
      // ++ 根据组件自动推断
      type ChildCtx = Exclude<ReturnType<Required<typeof Child>['setup']>, void | RenderFunction | Promise<any>>;
      <script lang="ts">
         export default   defineComponent({
            components: {Child},
            setup(){
             //定义类型
             const childRef = ref<null | ChildCtx>(null);
             onMouned(() => {
                childRef.value?.num; // 这里可以访问到 num 属性
      </script>
    复制代码
    分类:
    前端
    标签: