vue3+vite插件开发

插件开发目的:由于我司使用的前端技术栈为vue3+ts+vite2.X+axios,在前端代码框架设计初期,做了把axios挂载到proxy对象上的操作,具体可见我的另一篇文章vue3+TS自动化封装全局api_ts 封装+腾讯位置api-CSDN博客

现在可以实现vue2的类似this.$api.xxx去调用接口,但是vue2源码使用的是flow来实现,并且搭配typeScript不太友好(由于装饰器语法过于复杂,这里不讨论vue2+装饰器来使用typeScript),故vue2项目没有开发webpack插件去实现代码补全

这篇文章主要介绍的是vue3+ts+vite来开发时的代码补全情况

在使用vue/react+ts开发时,我们把api挂载到全局后,例如封装好axios后需要按模块划分请求,此时会创建一个modules文件夹,里面存放各个模块的请求,当把module所有的文件都动态挂载到proxy实例上时,我们可以通过proxy.$api.文件名.请求名去发起请求

例如:proxy.$api.test_api.test()

1.把modules下所有的api挂载到proxy对象上

这里以vite2和vite4.X举例

// vite 2.X
// src/api/index.ts
// 动态加载module下所有的文件
const files = import.meta.globEager('./module/*.ts')
const models= {}
for (const key in files) {const keys = {}for (const v in files[key]) {Object.assign(keys, { [v]: files[key][v] })}models[key.replace(/(\.\/module\/|\.ts)/g, '')] = keys
}
export default models
// vite4.X以上版本
// src/api/index.tsconst models = {}const modules = import.meta.glob('./module/*.ts')
const moduleEntries = Object.entries(module)for (const [key, apiFetchFn] of moduleEntries) {try {const module = await apiFetchFn()const keys = Object.fromEntries(Object.entries(module))models[key.replace(/(\.\/module\/|\.ts)/g, '')] = keys} catch (error) {console.error('API挂载初始化异常:', error)}
}export default models
// src/main.ts
import { createApp } from 'vue'
import api from '@/api'
const app = createApp(App)
app.config.globalProperties.$api = api
//src/xxx.vue
import { getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()!async function foo(){const res = await proxy.$api.test_api.testFetch()
}

2.为proxy使用$api添加类型提示

第一点我们已经完成把所有的请求挂载proxy上并且可以通过proxy.$api.xxx.xxx去发起请求,为proxy添加拥有$api的类型很简单,只需要在xxx.d.ts文件声明@vue/runtime-core添加类型即可

//src/global.d.ts
declare module '@vue/runtime-core' {interface ComponentCustomProperties {$api: any}
}

以上我们为proxy添加了$api属性,值为any,所以我们在使用proxy是会出现$api的代码提示,如下图

3.为$api添加代码提示

众所周知,在vue+ts开发的项目中,只要全局声明了XXX.d.ts文件,并且在里面使用declare声明的类型可以在全局访问到,那么我们思路可以放在声明一个xxx.d.ts文件,该文件的key可以取api/module下面的所有文件名,值直接使用typeScript的typeof import该文件即可获取到

3.1在api文件下新建Api.d.ts文件,里面声明所需要的文件类型,如下

        这里假使module文件夹已有test_api文件

declare namespace GlobalApi {interface Api {test_api: typeof import('@/api/module/test_api')}
}

3.2使用$api时出现代码提示

4.如何自动生成Api.d.ts文件内容呢

我想大家第一反应肯定是写脚本去处理,当module文件下的文件变动时,重新执行脚本即可,那么如何监听到module文件夹下文件的改动呢?但是我不想手动执行脚本怎么处理,这里我们可以使用nodejs的fs模块

4.1在根目录声明一个ts文件,起名为generateApi.ts(随意)

import fs from 'fs'
import type { Plugin } from 'vite'/*** @type 插件配置项*/
interface IPluginConfig {/**生成的.d.ts文件名 */fileName: string/**查找的文件夹名 */folderName: string
}/*** @method 更新Api.d.ts内容* @description 生成Api类型后挂载到proxy上获取proxy?.$api.xxx代码提示*/
function updateApiDeclaration(config: IPluginConfig) {const { fileName, folderName } = configconst moduleFiles = fs.readdirSync(folderName)const apiContent = generateApiDeclaration(moduleFiles)fs.writeFileSync(fileName, apiContent)
}/*** @method 根据api/module文件名生成Api.d.ts内容* @param {string[]}  moduleFiles 文件名*/
function generateApiDeclaration(moduleFiles: string[]) {const interfaceEntries = moduleFiles.map((filename) => `  ${filename.replace('.ts', '')}: typeof import('@/api/module/${filename.replace('.ts', '')}')`).join('\n  ')return `declare namespace GlobalApi {interface Api {${interfaceEntries}}
}
`
}/*** @method 使用fs观察module文件夹变动* @description 观察到文件夹内的文件变动后重新生成Api.d.ts文件*/
export default function watchFolderChange(pluginConfig: IPluginConfig): Plugin {return {name: 'watch-folder-plugin',config(config, { mode }) {if (mode === 'development') {fs.watch(pluginConfig.folderName, (eventType) => {if (['change', 'rename'].includes(eventType)) {updateApiDeclaration(pluginConfig)}})}},}
}

4.2 在vite.config.ts里引入

import watchFolderPlugin from './generateApi'export default defineConfig({plugins: [//...otherPluginswatchFolderPlugin({fileName: pathResolve('src/api/Api.d.ts'),folderName: pathResolve('src/api/module'),}),],// ...otherConfig})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/850284.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

flutter日历范围选择器

1.传入日期跨度,选择上架日期时,自动显示下架日期 2.手动选择上架日期和下架日期(图中下架日期自动填了只需CalendarDateRangePicker在initState方法中使用_startDate widget.initialStartDate; _endDate widget.initialEndDate;,而不直接…

【python】OpenCV—Blob Detection(11)

学习来自OpenCV基础(10)使用OpenCV进行Blob检测 文章目录 1、cv2.SimpleBlobDetector_create 中文文档2、默认 parameters3、配置 parameters附录——cv2.drawKeypoints 1、cv2.SimpleBlobDetector_create 中文文档 cv2.SimpleBlobDetector_create 是 O…

端午搞个零花钱,轻松赚取创业的第一桶金!2024最受欢迎的创业项目,2024新的创业机会

好好的端午节, 净给我添堵! 本来我打算在端午节愉快的玩耍, 结果一大早起床却看到舍友在给一堆设备充电, 然后装的整整齐齐, 满满一书包。 我好奇他小子这是要干嘛? 不会是打算今天回去给亲朋好友准备…

【动态规划-BM79 打家劫舍(二)】

题目 BM79 打家劫舍(二) 描述 你是一个经验丰富的小偷,准备偷沿湖的一排房间,每个房间都存有一定的现金,为了防止被发现,你不能偷相邻的两家,即,如果偷了第一家,就不能再偷第二家,如…

全面分析找不到msvcr120.dll,无法继续执行程序问题

在计算机使用过程中,我们可能会遇到一些错误提示,其中“找不到msvcr120.dll”就是常见的一种。那么,找不到msvcr120.dll是什么意思呢? 一,msvcr120.dll文件概述 msvcr120.dll 是 Microsoft Visual C Redistributable …

C++教程(003):运算符

3 运算符 作用:用于执行代码的运算 我们主要讲解以下运算符: 运算符类型作用算术运算符用于处理四则运算赋值运算符用于将表达式的值赋给变量比较运算符用于表达式的比较,并返回一个真值或假值逻辑运算符用于根据表达式的值返回真值或假值 …

详解 Flink 的时间语义和 watermark

一、Flink 时间语义类型 Event Time:是事件创建的时间。它通常由事件中的时间戳描述,例如采集的日志数据中,每一条日志都会记录自己的生成时间,Flink 通过时间戳分配器访问事件时间戳Ingestion Time :是数据进入 Flink…

el-table合计行前置在首行,自定义合计行方法

背景 el-table原生合计行是在标签内增加show-summary属性,在表尾实现设计合计,且只对表格当前页面显示的列数据进行合计。element-UI效果如下图所示。 现要求在首行显示合计行,并自定义合计逻辑实现如下效果。 图示表格中,成本…

【渗透测试】DC-1靶机实战(上)漏洞扫描获取反弹shell

目录 一、范围界定 二、信息收集 三、目标识别 1)主机发现 2)端口扫描 四. 服务枚举 1)网站首页 2)Web指纹识别 3)nikto报告 4)robots.txt 5)UPGRADE.txt 五. 漏洞映射 1&#xff…

万字长文|OpenAI模型规范(全文)

本文是继《OpenAI模型规范概览》之后对OpenAI Model Spec的详细描述,希望能对各位从事大模型及RLHF研究的朋友有帮助。万字长文,建议收藏后阅读。 一、概述 在AI的世界里,确保技术的行为符合我们的期望至关重要。OpenAI最近发布了一份名为Mo…

今天是放假带娃的一天

端午节放假第一天 早上5点半宝宝就咔咔乱叫了,几乎每天都这个点醒,准时的很,估计他是个勤奋的娃吧,要早起锻炼婴语,哈哈 醒来后做饭、洗锅、洗宝宝的衣服、给他吃D3,喂200ml奶粉、给他洗澡、哄睡&#xff0…

代码随想录算法训练营第二十二天

题目&#xff1a;216. 组合总和 III 这道题和上道题非常类似&#xff0c;大体框架一样只不过修改一下终止条件而已 值得注意的是其中的剪枝条件的设置 一是靠现有的元素和已经大于目标和的话就提前终止&#xff0c;另一个是其中循环那个剪枝可以记住 i < n - (k - path.s…

YOLOv8改进 | 卷积模块 | 在主干网络中添加/替换蛇形卷积Dynamic Snake Convolution

&#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 蛇形动态卷积是一种新型的卷积操作&#xff0c;旨在提高对细长和弯曲的管状结构的特征提取能力。它通过自适应地调整卷积核的权重&#xff0…

【每日刷题】Day59

【每日刷题】Day59 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;每日刷题&#x1f34d; &#x1f33c;文章目录&#x1f33c; 1. 1103. 分糖果 II - 力扣&#xff08;LeetCode&#xff09; 2. 1051. 高度检查器 - 力扣&#xff08…

电子纸在日化行业的全新应用

电子纸在日化行业的全新应用 项目背景 在一日化龙头企业他们的洗衣粉产线在AGV小车取料到运输到产品包装工序时&#xff0c;因为取料粉车无明显区分标识&#xff0c;但是产品系列有十大类。在未采用晨控电子纸之前现场采用一个转盘分为十个区域&#xff0c;取料工序上方会有一…

我也想拥有一个漂亮的网站

我也想拥有一个漂亮的网站 别人的公司几乎每个都有好看的网站&#xff0c;我也想拥有 如今在互联网上网站的存在已经非常的不稀奇了&#xff0c;可以在各大搜索引擎上面查到大量的网站&#xff0c;各行各业的网站都有&#xff0c;千奇百态&#xff0c;什么风格的网站都有…

JDK8安装详细教程教程-windows

&#x1f4d6;JDK8安装详细教程教程-windows ✅1. 下载✅2. 安装 ✅1. 下载 123云盘下载地址&#xff1a; JDK8 | JDK11 | JDK17 官方Oracle地址&#xff1a;https://www.oracle.com/java/technologies/downloads/archive/ ✅2. 安装 运行jdk-8u211-windows-x64.exe安装包文…

WebAPI AOP方式 异常方式 FilterAttribute、ActionFilterAttribute

》》 自定义异常处理特性 using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web; using System.Web.Http.Filters;namespace WebApplication11 {/// <summary>/// 异常处理特性/// </sum…

278 基于Matlab GUI的中重频PD雷达仿真系统

基于Matlab GUI的中重频PD雷达仿真系统。具有26页文档报告。仿真雷达信号的发射、传播、散射、接收、滤波、信号处理、数据处理的全部物理过程&#xff0c;因此应当实现对雷达发射机、天线、接收机、回波信号处理、数据处理的建模与仿真。程序已调通&#xff0c;可直接运行。 2…

使用OpenPCDet训练与测试Transformer模型:如何加载自己的数据集

引言 Transformer架构因其强大的序列处理能力和长距离依赖捕捉能力&#xff0c;在自然语言处理领域取得了巨大成功。近年来&#xff0c;这一架构也被引入3D物体检测领域&#xff0c;如Voxel Transformer等&#xff0c;显著提升了模型在复杂场景下的检测性能。OpenPCDet整合了多…