Vue3 + Vite批量导入模块 / 资源

简介: Vue3 + Vite批量导入模块 / 资源

在Vue项目开发中,我们常常会导入一些外部的模块,或者是自己写模块导入。

但是模块多了,一个个地导入很显然不是一个好办法,因此我们可以批量导入。

1,前置基础知识 - JavaScript模块化编程

在以往开发普通网页程序时,我们直接使用script标签引入了js文件即可调用其函数,但是在vue中你发现就不行了,因为vue也是使用了模块化编程标准。

通常我们可以把一个封装了很多要复用的函数和变量的js文件称作模块,模块必须暴露(导出)其中的变量、函数才能被外部导入并调用其中的函数。

现在常见的模块标准有两个:CommonJSES6

在这里我们着重讲解ES6模块。

(1) export语句 - 暴露函数和变量使外部调用

现在我们自己创建一个js文件表示我们自己的模块,里面封装一些常常复用的函数、变量等等,就需要使用export暴露出来。

// 导出常量aexportconsta='test';
// 导出函数myPrintexportfunctionmyPrint(msg) {
console.log('[]'+msg);
}

可见在定义变量/函数时在前面加上export即可。

除此之外,还可以批量导出:

consta='test';
functionmyPrint(msg) {
console.log('[]'+msg);
}
// 导出常量a和函数myPrintexport {
a,
myPrint};

(2) import语句 - 导入变量/函数并使用

上面封装好了函数、变量等等并导出了,但是还是不能直接使用的。需要在要使用的地方进行导入操作:

// 导入函数myPrint和常量aimport {
a,
myPrint} from'./mymodule.js';
// 使用导入的变量和函数console.log(a);
myPrint('msg');

这样就可以使用了。

可见import语法如下:

import { 变量1/函数1, 变量2/函数2, 变量3/函数3, ... } from'js文件路径';

需要注意,导入的变量和函数一次可以有多个,用大括号括起来,并且导入的变量/函数名必须和模块中导出的变量/函数名一致!

(3) import * as xxx语句 - 全部导入

对于需要导入很多的模块,我们import后面需要写一长串的导入的变量和函数,因此我们还可以一次性全部导入。

对于上面的mymodule里面导出了一个变量和一个函数,在此我们可以一次性全部导入:

// 一次性全部导入该模块的内容并命名为myimport*asmyfrom'./mymodules.js';
// 调用模块属性aconsole.log(my.a);
// 调用模块函数myPrintmy.myPrint('hhh');

可见,用import * as 名字 from '模块路径'的方式不仅可以方便地导入一个模块js文件的所有内容,还可以自己定义一个名字以方便调用。

(4) export default - 默认导出

上述的导出方式其实是命名式导出,其它文件导入时的变量/函数名必须和模块中导出的变量/函数名一致。

但是有时候不知道我们要导入的js文件中的函数/变量名怎么办呢?

可以使用默认导出,即export default语句,例如默认导出一个函数:

// 默认导出myPrint函数exportdefaultfunctionmyPrint(msg) {
console.log('[]'+msg);
}

默认导出后,导入时可以自行命名:

// 导入文件中默认导出的函数/变量并命名为pimportpfrom'./mymodule.js';
//使用p('msg');

可见这里没有使用大括号,并且导入时可以自行命名,不需要和原模块中函数名一样。

注意,一个js文件只能有一个默认导出!不能多次默认导出!

因此,一个有很多变量和函数的复用模块,我们可以这么写:

exportdefault {
// 变量aa: 'a',
// 函数myPrintmyPrint() {
console.log('aa');
  }
}

调用时:

importmfrom'./mymodule.js';
//使用console.log(m.a);
m.myPrint();

很显然,这里是直接默认导出了一个大的匿名JavaScript对象,并把变量、函数写在这个对象里面。然后再导入,调用其中变量/函数即可。

其实在vue开发中,我们用到的很多外部JavaScript的库,都是这么做的。

事实上,我们的Vue单文件组件原理不也是这样的?

2,在Vite工程中批量导入js模块

在之前的Vue-cli开发中,我们可以使用require.context()来实现批量导入。但是由于Vite是完全基于ES6模块的,因此就不能使用这种方式了。

当然,官方也提供了实现批量导入的方式,用import.meta.glob或者import.meta.globEager函数实现。前者懒加载的导入,后者则为直接导入。今天主要讲解后者。

例如我现在工程目录下src/assets/js下有三个js文件:

网络异常,图片无法展示
|

现在要在根组件App.vue批量导入它们,则在<script>部分开头写:

constimportModules=import.meta.globEager('./assets/js/*.js');

这样就导入了./assets/js下所有js模块文件。

当然这种方式也可以匹配多级目录

constimportModules=import.meta.globEager('./assets/js/**/*.js');

这样就导入了./assets/js下所有js文件及其子目录下的所有js文件。

在这里我们将其导入为一个变量importModules,这个变量里面到底是啥呢?我们在mounted函数里面打印一下看看:

console.log(importModules);

网络异常,图片无法展示
|

可见导入的是一个对象,这个对象中的每个属性即为模块路径,而对应的值中的default属性即为导入的模块本身,模块的函数变量等等都在里面。因此我们可以取导入的变量的每个属性下的default属性以调用我们的模块。

举个例子,现在要调用模块one中的print函数:

importModules['./assets/js/one.js'].default.print('hello');

到这相信大家又发现问题了:每次调用批量导入的模块,就要用模块的完整路径去取,还需要带上default属性,及其不方便。

我们能不能实现就用模块名(js文件名)去取出对应的模块呢?当然可以,事实上方法很多,我来讲一下我的思路。

我们将上述存放导入模块的变量importModules中的每个属性名都给用字符串裁剪的方式替换成模块名,并将每个属性对应的值直接替换为它的default值不就行了吗?我们来试一下子:

// 对批量导入存放模块的对象进行处理// 先获取其全部属性constkeys=Object.keys(importModules);
// 执行批量替换操作for (letpathofkeys) {
// 裁剪字符串方式得到路径中的文件名(无扩展名)letname=path.substring(path.lastIndexOf('/') +1, path.lastIndexOf('.js'));
// 对原对象执行添加新的属性并删除旧属性达到处理效果importModules[name] =importModules[path].default;
deleteimportModules[path];
}

现在,我们就可以很方便地进行调用了!

// 调用模块one的printimportModules.one.print('hello');
// 打印模块two的name属性console.log(importModules.two.name);

3,在Vite工程中批量导入图片/音频等静态资源

在Vite中如果是想要动态绑定图片音频视频等等,也是要用import语句的,同样地图片多了,不想一个个地import应当怎么做呢?

事实上,我们还可以用import.meta.globEager批量导入静态资源例如图片音频等等。

假设现在在src/assets/image下有很多图片。

网络异常,图片无法展示
|

我们仍然可以用上面的方式批量导入:

constimportImages=import.meta.globEager('./assets/image/*');

方式和上面一模一样,只不过这次导入的是静态资源,所以说上述importImagesdefault变成了对应资源的路径。

打印看一看:

网络异常,图片无法展示
|

同样地,我们可以把上述导入的每个default部分存起来再使用v-for批量呈现,试一下子,整个Vue文件代码如下:

<template><divclass="app"><!-- 然后就可以批量呈现了 --><imgv-for="item in images":src="item"height="150"/></div></template><script>constimportImages=import.meta.globEager('./assets/image/*');
exportdefault {
data() {
return {
// 存放批量导入的图片images: []
  }
 },
mounted() {
// 把导入的对象中每个default属性(对应实际导入的图片)取出来放到data中的变量images中去for (letpathinimportImages) {
this.images.push(importImages[path].default);
  }
 }
}
</script>

效果:

网络异常,图片无法展示
|

可见Vite中的批量导入非常方便,无论是模块还是资源都可以。对于静态资源,我们是不是还可以用这个批量导入机制,结合我之前写的判断各个资源加载完成的方法的文章,更加简单地实现网站资源加载检测并制作进度条呢?

相关文章
|
25天前
|
存储 JavaScript 前端开发
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
【10月更文挑战第21天】 vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
vue3的脚手架模板你真的了解吗?里面有很多值得我们学习的地方!
|
21天前
|
JavaScript 前端开发 开发者
Vue 3中的Proxy
【10月更文挑战第23天】Vue 3中的`Proxy`为响应式系统带来了更强大、更灵活的功能,解决了Vue 2中响应式系统的一些局限性,同时在性能方面也有一定的提升,为开发者提供了更好的开发体验和性能保障。
50 7
|
23天前
|
前端开发 数据库
芋道框架审批流如何实现(Cloud+Vue3)
芋道框架审批流如何实现(Cloud+Vue3)
41 3
|
21天前
|
JavaScript 数据管理 Java
在 Vue 3 中使用 Proxy 实现数据双向绑定的性能如何?
【10月更文挑战第23天】Vue 3中使用Proxy实现数据双向绑定在多个方面都带来了性能的提升,从更高效的响应式追踪、更好的初始化性能、对数组操作的优化到更优的内存管理等,使得Vue 3在处理复杂的应用场景和大量数据时能够更加高效和稳定地运行。
39 1
|
21天前
|
JavaScript 开发者
在 Vue 3 中使用 Proxy 实现数据的双向绑定
【10月更文挑战第23天】Vue 3利用 `Proxy` 实现了数据的双向绑定,无论是使用内置的指令如 `v-model`,还是通过自定义事件或自定义指令,都能够方便地实现数据与视图之间的双向交互,满足不同场景下的开发需求。
44 1
|
24天前
|
前端开发 JavaScript 容器
在 vite+vue 中使用@originjs/vite-plugin-federation 模块联邦
【10月更文挑战第25天】模块联邦是一种强大的技术,它允许将不同的微前端模块组合在一起,形成一个统一的应用。在 vite+vue 项目中,使用@originjs/vite-plugin-federation 模块联邦可以实现高效的模块共享和组合。通过本文的介绍,相信你已经了解了如何在 vite+vue 项目中使用@originjs/vite-plugin-federation 模块联邦,包括安装、配置和使用等方面。在实际开发中,你可以根据自己的需求和项目的特点,灵活地使用模块联邦,提高项目的可维护性和扩展性。
|
24天前
|
前端开发 JavaScript
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef
简记 Vue3(一)—— setup、ref、reactive、toRefs、toRef
|
25天前
Vue3 项目的 setup 函数
【10月更文挑战第23天】setup` 函数是 Vue3 中非常重要的一个概念,掌握它的使用方法对于开发高效、灵活的 Vue3 组件至关重要。通过不断的实践和探索,你将能够更好地利用 `setup` 函数来构建优秀的 Vue3 项目。
|
25天前
|
缓存 JavaScript UED
Vue 中异步加载模块的方式
【10月更文挑战第23天】这些异步加载模块的方式各有特点和适用场景,可以根据项目的需求和架构选择合适的方法来实现模块的异步加载,以提高应用的性能和用户体验
|
25天前
|
JavaScript 测试技术 UED
解决 Vue 项目中 Tree shaking 无法去除某些模块
【10月更文挑战第23天】解决 Vue 项目中 Tree shaking 无法去除某些模块的问题需要综合考虑多种因素,通过仔细分析、排查和优化,逐步提高 Tree shaking 的效果,为项目带来更好的性能和用户体验。同时,持续关注和学习相关技术的发展,不断探索新的解决方案,以适应不断变化的项目需求。
下一篇
无影云桌面