Vue 批量注册组件实现动态组件技巧

介绍

Vue 动态组件的应用场景很多,可应用于动态页签,动态路由等场景,其核心原理是批量注册。在Vue2和Vue3中实现原理相同,只是语法略有差异。

Vue2 实现

基于 webpack

require.context() 是webpack提供的一个自动导入的API
参数1:加载的文件目录
参数2:是否加载子目录
参数3:正则,匹配文件
返回值:导入函数 fn
使用require提供的函数context加载某一个目录下所有的.vue后缀的文件,他的返回值是一个对象,对象里面有一个属keys(), 可以获取所有的文件路径,我们可以遍历importFn.keys(),最后在遍历中使用

首先先描述下应用场景,比如我想在父容器遍历组件集合,根据组件类型(字符串)来首先动态加载组件,如下图:
在这里插入图片描述
如果要是按正常一个个注册的话,也是可以的,就是代码冗余多,不够优雅,所以需要一个方法来实现,这个方法就放到一个JS里去,然后把该index.js直接丢到widget-attr文件夹里.

//index.js
const requireComponent = require.context('./', false, /\w+\.vue$/)
let comps = {}
requireComponent.keys().map(fileName => {let comp = requireComponent(fileName).default;comps[comp.name] = comp
})
export default comps;

然后在页面引用,如下图:
在这里插入图片描述
好了,到这里简简单单就实现了,我现在整个项目需要这样批量注册的场景也就两三个,所以我在需要批量注册的组件对应的文件夹就放置这个一个index.js就能实现了,如果实际场景不想放那么多,可以自行稍微改造下,传个路径进去,我Vue3版本就是这样实现的

Vue3 实现

基于 Vite

const components = import.meta.glob("./*.vue");
//注意 :  import.meta.glob 不支持变量,

Vue3 使用 组合式 ,方法里也用到了Vite的语法,首页也要把核心代码封装到 dynamicComponents.js里面

详细如下

// utils/dynamicComponents.js
import { defineAsyncComponent } from 'vue';
function loadComponentsFromFolder(folderPath) {const components = {};let modules = import.meta.glob('@/components/form-designer/widget/*.vue', { eager: false });if (folderPath == 'widgetArrt') {modules = import.meta.glob('@/components/form-designer/widget/widget-attr/*.vue', { eager: false });}for (const path in modules) {const componentName = path.match(/\/([^/]+)\.vue$/)[1];components[componentName] = defineAsyncComponent(modules[path]);}return components;
}
export default loadComponentsFromFolder;

这个并不完美,理想中应该是根据传参(需要动态注册的组件所在文件夹路径)来实现,但是,如下目前好像并不支持:

// utils/dynamicComponents.js
function loadComponentsFromFolder(folderPath) {//省略...modules = import.meta.glob(`${folderPath}/*.vue`, { eager: false   });//省略...
}
export default loadComponentsFromFolder;

这样写会报错,提示import.meta.glob不支持变量.

[plugin:vite:import-glob] Invalid glob import syntax:Expected glob to be a string, but got dynamic template literal//大致意思: 只能使用文本,而我们的 path 使用了变量,所以会报错.

这个有其他解决办法,待会下面会说到,因为我在该项目批量注册应用场景不多,所以我就直接传参判断来写死了.
.接下来就是引用了,如下图:
在这里插入图片描述
至此,就实现批量动态注册了,另外注意, 组件集合不要用绑定模式,虽然不报错,但是会报黄提示影响效率

 // let components =ref({})  //不要写成响应式的了,会有性能风险提示let components = {} components = loadComponentsFromFolder('widget')

最后

用其他办法来解决这个问题吧,有点复杂,有更好办法的小伙伴可以留言~

使用 fs 模块读取文件列表:
在 Node.js 环境中使用 fs 模块读取指定文件夹下的文件列表。
将文件列表传递给前端,前端再使用 import() 动态导入这些文件。
前端动态导入:前端根据接收到的文件列表动态导入组件。
实现步骤
1. 后端读取文件列表
首先,在 Vite 项目的 vite.config.js 或者单独的 Node.js 脚本中,使用 fs 模块读取文件列表,并将结果暴露给前端。javascript
// vite.config.js 或者单独的 Node.js 脚本
const fs = require('fs');
const path = require('path');function getComponentPaths(folderPath) {const baseFolderPath = path.resolve(__dirname, 'src/components/form-designer/widget/');const fullFolderPath = folderPath ? path.join(baseFolderPath, folderPath) : baseFolderPath;const files = fs.readdirSync(fullFolderPath);const componentPaths = files.filter(file => file.endsWith('.vue')).map(file => path.join(fullFolderPath, file));return componentPaths.map(p => p.replace(/\\/g, '/').replace(path.resolve(__dirname, 'src/'), '@/'));
}module.exports = {getComponentPaths,
};
2. 前端动态导入
在前端,使用 import() 动态导入这些文件。javascript
// utils/dynamicComponents.js
import { defineAsyncComponent } from 'vue';const componentCache = {};async function loadComponentsFromFolder(folderPath) {// 检查缓存if (componentCache[folderPath]) {return componentCache[folderPath];}// 获取文件路径列表const componentPaths = await fetchComponentPaths(folderPath);const components = {};// 动态导入模块await Promise.all(componentPaths.map(async (path) => {const componentName = path.match(/\/([^/]+)\.vue$/)[1];components[componentName] = defineAsyncComponent(() => import(path));}));// 缓存结果componentCache[folderPath] = components;return components;
}async function fetchComponentPaths(folderPath) {// 这里假设你有一个 API 端点来获取文件路径列表const response = await fetch(`/api/get-component-paths?folderPath=${folderPath}`);const data = await response.json();return data.paths;
}export default loadComponentsFromFolder;
3. 创建 API 端点
在 Vite 项目中创建一个简单的 API 端点来返回文件路径列表。javascript
// server/index.js
const express = require('express');
const { getComponentPaths } = require('../vite.config');const app = express();
const port = 3000;app.get('/api/get-component-paths', (req, res) => {const folderPath = req.query.folderPath;const paths = getComponentPaths(folderPath);res.json({ paths });
});app.listen(port, () => {console.log(`Server running at http://localhost:${port}`);
});
使用示例
在组件或页面中使用 loadComponentsFromFolder 函数时,只需传递不同的 folderPath 参数即可动态注册不同路径下的组件。javascript
// 在某个 Vue 组件中使用
<script setup>
import { ref, onMounted } from 'vue';
import loadComponentsFromFolder from '@/utils/dynamicComponents';const folderPath = 'widgetAttr'; // 可以根据实际需求动态设置
const dynamicComponents = ref({});onMounted(async () => {dynamicComponents.value = await loadComponentsFromFolder(folderPath);
});
</script><template><div><component v-for="(component, name) in dynamicComponents" :is="component" :key="name"></component></div>
</template>
注意事项
文件路径处理:确保文件路径在前后端一致,特别是在 Windows 系统中,路径分隔符需要转换。
API 端点:确保 API 端点能够正确返回文件路径列表。
性能优化:如果组件数量较多,可以考虑使用懒加载和缓存机制来优化性能。
通过这种方式,你可以根据路径参数动态注册不同文件夹下的组件,而不需要使用 if-else 判断。

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

仓储管理系统-综合管理(源码+文档+部署+讲解)

本文将深入解析“仓储管理系统-综合管理”的项目&#xff0c;探究其架构、功能以及技术栈&#xff0c;并分享获取完整源码的途径。 系统概述 仓储管理系统-综合管理是一个全面的仓库管理解决方案&#xff0c;旨在通过集成多种功能模块来优化仓库操作和管理流程。该系统提供了…

xxl-job 是如何注册、注销、维持存活态

我们通过源码发现&#xff0c;xxl-job主要是由客户端发起的注册和存活上报(心跳检测)的&#xff1b; 主要是执行器在启动时&#xff0c;会初始化一个线程&#xff0c;每隔30秒请求调度中心接口&#xff0c;维护存活状态&#xff1b; 注册接口/上报接口&#xff1a;/api/regis…

Ps:OpenColorIO 设置

Ps菜单&#xff1a;编辑/OpenColorIO 设置 Edit/OpenColorIO Settings 在专业的图像编辑和色彩管理工作流程中&#xff0c;准确的色彩呈现和转换至关重要。OpenColorIO&#xff08;OCIO&#xff09; 是一种开源的色彩管理框架&#xff0c;广泛应用于影视、动画和视觉特效行业。…

如何抓取某大学网站专业录取分数

当我们在浏览器中浏览网页时&#xff0c;网页上显示的数据实际上已经被加载到浏览器内存中&#xff0c;只是以一种可视化的方式呈现出来。那么是否有一种简便的方法可以将这些数据从网页中提取出来&#xff0c;并保存为表格格式呢&#xff1f; 这是某大学的专业分数录取情况数…

举例理解LSM-Tree,LSM-Tree和B+Tree的比较

写操作 write1&#xff1a;WAL 把操作同步到磁盘中WAL做备份&#xff08;追加写、性能极高&#xff09; write2&#xff1a;Memtable 完成WAL后将(k,v)数据写入内存中的Memtable&#xff0c;Memtable的数据结构一般是跳表或者红黑树 内存内采用这种数据结构一方面支持内存…

JAVA开源项目 微服务在线教育系统 计算机毕业设计

博主说明&#xff1a;本文项目编号 T 060 &#xff0c;文末自助获取源码 \color{red}{T060&#xff0c;文末自助获取源码} T060&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析…

深入浅出《钉钉AI》产品体验报告

1. 引言 随着人工智能技术的迅猛发展&#xff0c;企业协同办公领域迎来了新的变革。钉钉作为阿里巴巴集团旗下的企业级通讯与协同办公平台&#xff0c;推出了钉钉AI助理&#xff0c;旨在提高工作效率&#xff0c;优化用户体验。本报告将对钉钉AI助理进行全面的产品体验分析&am…

揭开基础动销方案的神秘面纱

在如今竞争激烈的市场大环境下&#xff0c;产品实现有效动销可谓是企业生存发展的关键所在。而基础动销方案&#xff0c;正是推动产品销售的重要利器。 基础动销方案到底是什么呢&#xff1f;它指的是企业为促进产品销售&#xff0c;运用一系列营销手段和策略&#xff0c;提升产…

YOLO v5 Series - Image Comparison

图像相似度 Image Similarity 图片差异度 Image Dissimilaritypuzzle-diff pacman -S autoconf automake base-devel libtool pacman -S mingw-w64-x86_64-libgdautogen /opt/admin/libpuzzle>./configure configure: loading site script /etc/config.site che…

sqli—labs靶场 5-8关 (每日4关练习)持续更新!!!

Less-5 上来先进行查看是否有注入点&#xff0c;判断闭合方式&#xff0c;查询数据列数&#xff0c;用union联合注入查看回显位&#xff0c;发现到这一步的时候&#xff0c;和前四道题不太一样了&#xff0c;竟然没有回显位&#xff1f;&#xff1f;&#xff1f; 我们看一下源…

InnoDB引擎

6.1 逻辑存储结构 InnoDB的逻辑存储结构如下图所示: 6.2 架构 6.2.1 概述 MySQL5.5 版本开始&#xff0c;默认使用InnoDB存储引擎&#xff0c;它擅长事务处理&#xff0c;具有崩溃恢复特性&#xff0c;在日常开发中使用非常广泛。下面是InnoDB架构图&#xff0c;左侧为内存结…

C#与C++交互开发系列(二十二):跨进程通信之使用基于HTTP协议的REST风格的API

1. 前言 REST API&#xff08;Representational State Transfer Application Programming Interface&#xff09;是一种基于HTTP协议的通信方式&#xff0c;广泛用于网络服务和分布式应用程序之间的通信。通过REST API&#xff0c;可以让C#和C应用程序进行跨进程、甚至跨平台的…

想让三维模型与实时视频融合?这款软件值得一试

视频融合&#xff0c;是指将视频数据投影到地理特征表面&#xff0c;并通过相应姿态参数控制投影效果的一种三维展示方式&#xff0c;实现了三维模型与实时视频的融合。 四维轻云是一款轻量化的地理空间数据管理云平台&#xff0c;支持地理空间数据的在线管理、编辑以及分享。…

汉化版WinHex和CFF Explorer下载及程序脱壳后修复,重建引入表,修改程序PE文件(附下载链接)

前言 现有一个加壳程序&#xff0c;要求对程序脱壳&#xff0c;需要修复脱壳后的程序 使用PEiD查壳&#xff0c;显示为NsPack 1.4 -> Liuxingping [Overlay] * 先定位程序的OEP&#xff0c;使用od打开程序&#xff0c;看到有压入栈的操作 进行查找&#xff0c;查找命令序列…

STM32F407简单驱动步进电机(标准库)

配置 单片机型号&#xff1a;STM32F104ZGT6 步进电机&#xff1a;YK28HB40-01A 驱动器&#xff1a;YKD2204M-Plus 接线方式&#xff1a; pu&#xff1a;接对应的产生PWM的引脚&#xff0c;这里接PF9&#xff0c;对应TIM14_CH1通道&#xff01; pu-&#xff1a;接单片机的G…

linux-DNS解析

dns解析 dns&#xff1a;域名系统&#xff0c;将域名和ip地址互相映射的一个分布式的数据库&#xff0c;方便用户访问互联网。 ip地址&#xff1a;是所有设备和网站在互联网上的唯一地址&#xff0c;通信一定是ip和ip之间的通信。 dns解析&#xff1a;根据域名在互联网当中找…

光伏电站容量计算方法科普

光伏电站的容量计算是设计和评估光伏系统性能的关键步骤。通过了解光伏电站的容量&#xff0c;我们可以预估其发电量&#xff0c;优化系统设计&#xff0c;并确保系统能满足电力需求。本文将详细介绍几种常见的光伏电站容量计算方法&#xff0c;并特别介绍小程序“光伏一点通”…

采集opc da 转 profinet IO项目案例

目录 1 案例说明 1 2 VFBOX网关工作原理 1 3 应用条件 2 4 查看OPC DA服务器的相关参数 2 5 配置网关采集opc da数据 4 6 用profinet IO协议转发数据 6 7 在服务器上运行仰科OPC DA采集软件 9 8 案例总结 11 1 案例说明 在OPC DA服务器上运行OPC DA client软件查看OPC DA服务…

循环矩阵和BCCB矩阵与向量乘积的快速计算——矩阵向量乘积与频域乘积之间的转换

目录 循环矩阵循环矩阵的定义特征值与特征向量循环矩阵的对角化 循环矩阵与向量的乘积 BCCB矩阵BCCB矩阵的定义BCCB矩阵的对角化BCCB 矩阵与向量的乘积BCCB 矩阵与向量乘积的实现 总结 循环矩阵&#xff08;Circulant Matrix&#xff09;和块循环对称矩阵&#xff08;Block Cir…

(动画版)排序算法 -希尔排序

文章目录 1. 希尔排序&#xff08;Shellsort&#xff09;1.1 简介1.2 希尔排序的步骤1.3 希尔排序的C实现1.4 时间复杂度1.5 空间复杂度1.6 希尔排序动画 1. 希尔排序&#xff08;Shellsort&#xff09; 1.1 简介 希尔排序&#xff08;Shells Sort&#xff09;&#xff0c;又…