美文网首页前端开发那些事儿前端大前端
vue一键引入指定文件夹下的组件(不限于vue/.vue文件/.

vue一键引入指定文件夹下的组件(不限于vue/.vue文件/.

作者: 冷r | 来源:发表于2022-04-01 16:13 被阅读0次

    一、前言

    在工作中经常通过一些小细节来增加代码可读性,让代码看起来更加优雅,同时可以减少不必要的操作和时间。

    通常会遇到需要引入一堆功能或作用类似文件,不过已经给出了对应的Api可以优雅的解决


    示例

    二、正片

    这里以框架vue在不同构建环境为例(webpack、vite)

    1. webpack

    先瞅代码

    <script>
      const allComponents = require.context("./components", true, /\.vue$/);
      let res_components = {};
      allComponents.keys().forEach((item) => {
        let comp = allComponents(item);
        let name = comp.default.name;
        res_components[name] = comp.default;
      });
    
    export default {
      name: 'StudentList',
      components: { ...res_components },
    }
    </script>
    
    require.context() 是什么

    一个webpack的api,通过执行require.context函数获取一个特定的上下文,主要用来实现自动化导入模块,在前端工程中,如果遇到从一个文件夹引入很多模块的情况,可以使用这个api,它会遍历文件夹中的指定文件,然后自动导入,使得不需要每次显式的调用import导入模块

    require.context() 用法
      //传入参数
      require.context(directory, useSubdirectories = false, regExp = /^.//);
      //返回的函数
      function webpackContext(req) {return __webpack_require__(webpackContextResolve(req))};
    

    接受三个参数:require.context(directory,useSubdirectories,regExp)
    directory:说明需要检索的目录 ,你要引入文件的目录
    useSubdirectories:是否要查找该目录下的子级目录
    regExp:匹配文件的正则表达式,匹配要引入的文件 ,一般是文件名

    返回的函数:function webpackContext(req) {return __webpack_require__(webpackContextResolve(req))};
    函数有三个属性:resolve 、keys、id
    resolve: 是一个函数,他返回的是被解析模块的id ,接受一个参数request。
    keys: 也是一个函数,他返回的是一个数组,该数组是由所有可能被上下文模块解析的请求对象组成
    id:是上下文模块里面所包含的模块 id. 它可能在你使用 module.hot.accept 的时候被用到

    2. vite

    先瞅代码

    <script>
      import { defineComponent} from "vue";
    
      const allComponents = import.meta.globEager("../components/*.vue");
      let res_components = {};
      Object.keys(allComponents).forEach((item) => {
        let comp = allComponents[item];
        let name = comp.default.name;
        res_components[name] = comp.default;
      });
    
      export default defineComponent({
        components: { ...res_components },
      });
    </script>
    
    

    在使用vite 时,发现不能使用require.context 自动导入,可以使用import.meta.globEager或import.meta.glob替换

    import.meta.glob()/import.meta.globEager()是什么

    vite的glob函数是基于fast-glob实现的。fast-glob是node.js非常快速和高效的glob库提供了遍历文件系统和返回路径名的方法,这些路径名根据 Unix Bash shell 使用的规则和一些简化的规则返回匹配一组定义的指定模式,同时以任意顺序返回结果。快速、简单、有效。

    import.meta.glob 为过动态导入,构建时,会分离为独立的 chunk
    import.meta.globEager 为直接引入

    import.meta.glob()/import.meta.globEager()需要注意什么
    • 这只是一个 Vite 独有的功能而不是一个 Web 或 ES 标准
    • 必须是相对路径(以 ./ 开头)或绝对路径(以 / 开头,相对于项目根目录解析)或一个别名路径
    • Glob 匹配是使用 fast-glob 来实现的 —— 阅读它的文档来查阅 支持的 Glob 模式
    • glob 的导入不接受变量,你应直接传递字符串模式。
    • glob 模式不能包含与包裹引号相同的引号字符串(其中包括 '",```),例如,如果你想实现 '/Tom\'s files/**' 的效果,请使用 "/Tom's files/**" 代替。

    三、结束总结

    此文只是已vue引用组件为例,只限于参考,具体场景再稍稍调整

    适用场景

    • 在vuex中 多个modules模块 需要使用 import 一个一个引入
    • 如果页面需要导入多个组件时,一般的写法
    • 遍历目录所有图片、加载所有的图片
    • 等等。。。。。。。。

    遇到的问题及解决方法

    问题:引用的文件在同一目录,引用时带了此文件。
    方法: let fileName = item.replace(/^.+[/\w+]/(.).\w+/, "1");//取所有文件名称
    if (fileName === "index") return;//过滤当前文件

    相关文章

      网友评论

        本文标题:vue一键引入指定文件夹下的组件(不限于vue/.vue文件/.

        本文链接:https://www.haomeiwen.com/subject/endnjrtx.html