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

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

html 复制代码
<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类型,效果如下:

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

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

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

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

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

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

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

typescript 复制代码
import { ref } from "vue";

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

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

相关推荐
AI情绪识别开源3 小时前
HFpEF 心房-心室耦联效率无创监测方向(AVCEI)
typescript·laravel·perl
专业程序开发源4 小时前
springboot简历管理系统81389-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·php·课程设计
专业程序开发源4 小时前
springboot社区养老系统44071-计算机课程设计、毕业设计
vue.js·spring boot·后端·python·django·php·课程设计
凤城老人4 小时前
从 PyQt6 到 Electron:给 Edge TTS 做一个“多角色配音机“的踩坑手记
javascript·typescript·electron
码艺-Alimjan5 小时前
Vben Admin 新增维吾尔语 Vben-Modal的关键坑之一
前端·javascript·vue.js
星光开发者6 小时前
基于决策树随机森林算法的小说推荐系统的设计与实现-计算机毕设【课程设计】78485
vue.js·算法·微信小程序·django·php·课程设计·express
vx_Biye_Design7 小时前
springboot高校选课系统82776-计算机课程设计、毕业设计
java·vue.js·spring boot·后端·spring·课程设计·express
niyongsheng7 小时前
后端零改动,给若依换一套现代化前端
vue.js·开源·node.js
用户91775337187510 小时前
从零封装一个地图组件库:OpenLayers + Vue 的工程化实践
vue.js
雪芽蓝域zzs11 小时前
第7节:多选模式、自定义选项渲染、受控弹窗显隐
vue.js·elementui