Vue3中组件使用ref时获取组件类型推导

本文由 ChatMoney团队出品

我们在使用Vue3+ts开发时,常常会用到一些第三方组件库,比如Element-Plus UINavie UI等,这些UI框架中有些组件常常会暴露一些方法给我们便捷的去实现各种复杂的交互,我们经常会像下面这样去给组件定义一个ref去获取组件的实例:

<template>
  <div>
    <el-drawer ref="drawerRef" v-model="showDrawer">
      <el-button type="primary" @click="closeHandle">关闭</el-button>
    </el-drawer>
  </div>
</template>

<script setup lang="ts">
import { ref } from "vue";
import { ElDrawer } from "element-plus";

const drawerRef = ref();
const showDrawer = ref<boolean>(true);

const closeHandle = () => {
  drawerRef.value.handleClose();
};
</script>

这个方法可以正常使用,但是没有任何的ts类型推导,这也就丧失了一部分我们使用ts的初衷。由于我们没有给ref传入任何的泛型,所以drawerRef是any类型,效果如下:

Vue3中组件使用ref时获取组件类型推导
Vue3中组件使用ref时获取组件类型推导

此时,我们想到一个方法,就是尝试给const drawerRef = ref()定义类型,我们第一想到的肯定是将组件传进去不就好了,但其实这样会报错,效果如下:

Vue3中组件使用ref时获取组件类型推导

因为传入的ElDrawer实例本质就是一个组件对象,我们需要传入的是类型,所以我们又会想到使用typeof来获取他的类型不就行了吗,因为在js中,typeof得到的是js中的类型,他是运行时的,但在ts中将typeof写到类型标注的位置的话,得到的是ts的类型,我们来试试看效果怎么样:

Vue3中组件使用ref时获取组件类型推导
Vue3中组件使用ref时获取组件类型推导

此时我们又会看到,类型是有了,但是获取到的是组件配置对象的类型,是通过DefineComponent来得到的,这不是我们想要的类型,我们想要的是通过这个组件配置对象生成的一个组件实例。

接下来重点来了,有一个ts的一个工具叫InstanceType,这个工具可以用来获取一个对象的实例,我们加上去的效果如下:

Vue3中组件使用ref时获取组件类型推导

捕捉到了这个组件暴露出来的handleClose方法,现在终于可以获取到我们想要的类型了。

……但还没完,我们假设每次要使用这个方法,都要写这么一坨东西进去太麻烦了,为了提升便捷程度我们可以将它封装成一个hook,这样我们每次调用他就不需要这么麻烦。

根据刚刚的理解,我们最终得到了以下封装结果:

import { ref } from "vue";

/**
 * 组件类型标注
 * @param _component 组件实例
 * @returns 完整类型标注的响应式组件实例
 */
export const useComponentRef = <T extends abstract new (...args: any) => any>(
  _component: T
) => {
  return ref<InstanceType<T>>();
};

此时,我们只需要将组件传入这个hook就可以得到一个有类型推导的组件实例对象,非常的方便😎。

Vue3中组件使用ref时获取组件类型推导

关于我们

本文由ChatMoney团队出品,ChatMoney专注于AI应用落地与变现,我们提供全套、持续更新的AI源码系统与可执行的变现方案,致力于帮助更多人利用AI来变现,欢迎进入ChatMoney获取更多AI变现方案!

ChatMoney的头像ChatMoney
上一篇 2024年 7月 11日 上午11:20
下一篇 2024年 7月 16日 上午10:08

相关推荐

  • php数据结构之链表

    本文由 ChatMoney团队出品 链表的基本概念 链表(Linked List)是一种常见的数据结构,它由一系列节点组成,每个节点除了存储数据外,还包含指向下一个节点的指针。与数组相比,链表在插入和删除操作上具有更高的效率,因为它们不需要移动大量的元素。 链表的种类 单链表:每个节点仅包含一个指向下一个节点的指针。 双链表:每个节点包含两个指针,一个指向下…

    2024年 6月 27日
    269
  • Android Studio下载Gradle超时解决方案

    本文由 ChatMoney团队出品 Android Studio 找到项目中 gradle 配置文件的路径,我的路径为 /你的项目路径/gradle/wrapper/gradle-wrapper.properties,里面对应内容应该如下所示: 超时原因是因为as(Android Studio,此后简称 as)中默认是从gradle官网去下载,此时我们有一个…

    2024年 7月 17日
    157
  • PHP开发工具:打造高效的编码体验

    本文由 ChatMoney团队出品 在PHP开发领域,选择正确的工具可以极大地提升开发效率和代码质量。 集成开发环境(IDE) PHPStorm 是一个强大的IDE,专为PHP开发设计。它提供了丰富的功能,如智能代码补全、代码分析、实时错误预防、重构工具、数据库工具和版本控制集成。 安装与配置PHPStorm 代码编辑器 Visual Studio Code…

    2024年 7月 16日
    140
  • PHP的命名空间

    本文由 ChatMoney团队出品 PHP 命名空间:模块化和避免命名冲突 在 PHP 项目中,命名空间用于对代码进行模块化和避免命名冲突,尤其在大型项目或使用第三方库时尤为重要。本文将介绍如何使用 PHP 命名空间来组织你的代码。 什么是命名空间 命名空间是通过 namespace 关键字定义的。它们提供了一种方法来封装一组相关的类、接口、函数和常量,从而…

    2024年 7月 31日
    166
  • php 简单的单例模式

    本文由 ChatMoney团队出品 单例模式是一种常用的设计模式,它的核心思想是确保一个类只有一个实例,并提供一个全局访问点来获取这个实例。在 PHP 中实现单例模式通常有三种形式:饿汉式(Eager)、懒汉式(Lazy)和登记式(Register)。 使用注意事项: 不要使用反射(Reflection)机制来创建单例,因为这会实例化一个新的对象。 在使用懒…

    2024年 7月 2日
    173

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信