2
场景

我们在开发项目的时候,会遇到某个组件需加载多个组件,正常的情况下;我们会用一下方式去引入:

  import A from './components/a.vue'
  import B from './components/b.vue'
  import C from './components/c.vue'
  
  components: {
          A,
          B,
          C
   },
    

或者直接用异步组件的方式:

components: {
      A: resolve => require(['./components/a.vue'],resolve),
      B: resolve => require(['./components/b.vue'],resolve),
      c: resolve => require(['./components/c.vue'],resolve),
    },

只引入三个还好,如果需要引入很多呢?

  • 代码看起来很乱
  • 不便于维护、不优雅

今天尝试用了webpack中 require.context,完美解决了这个问题。
官方文档
其实VUE官方也提供了这种解决方案;传送门

  • 基本用法

image.png

require.context接收三个参数:

  1. 需要搜索的文件夹目录(必传)
  2. 是否需要搜索它的子孙目录,默认为false
  3. 匹配文件名的正则表达式

引入我们的组件便可以这么做:

const requireComponent = require.context(
  // 其组件目录的相对路径
  './components',
  // 是否查询其子目录
  false,
  // 匹配基础组件文件名的正则表达式
  /Base[A-Z]\w+\.(vue|js)$/
)

我们可以再控制台打印这个requireComponent,会得到如下:

webpackContext(req) {
    var id = webpackContextResolve(req);
    return \_\_webpack\_require\_\_(id);
}

再深入的我就没去看了,以后慢慢深挖;

  • 应用到项目中的代码如下

在libs文件夹下创建requireComponents.js文件

/** 利用require.context动态引入指定目录下的所有.vue组件,并注册为全局组件 **/
import Vue from 'vue'
const requireAreaComponent = require.context(
  // 其组件目录的相对路径
  '../view/components/AreaBudgetManagement/ReportsCheckTemplate/childTemplate',
  // 是否查询其子目录
  false,
  // 匹配基础组件文件名的正则表达式
  /Base[A-Z]\w+\.(vue|js)$/
)
const requireProjectComponent = require.context(
  // 其组件目录的相对路径
  '../view/components/GroupBudgetManagement/ReportsCheckTemplate/childTemplate',
  // 是否查询其子目录
  false,
  // 匹配基础组件文件名的正则表达式
  /Base[A-Z]\w+\.(vue|js)$/
)

console.log("requireProjectComponent", requireProjectComponent)
const requireComp = (r) => {
  r.keys().forEach(fileName => {
    // 获取组件配置
    const componentConfig = r(fileName)

    // 获取组件的 PascalCase 命名
    const componentName = upperFirst(
      camelCase(
        // 获取和目录深度无关的文件名
        fileName
        .split('/')
        .pop()
        .replace(/\.\w+$/, '')
      )
    )

    // 全局注册组件
    Vue.component(
      componentName,
      // 如果这个组件选项是通过 `export default` 导出的,
      // 那么就会优先使用 `.default`,
      // 否则回退到使用模块的根。
      componentConfig.default || componentConfig
    )
  })
}
// 注册区域、集团里明细页面所有组件
[requireAreaComponent,requireProjectComponent].forEach( item => requireComp(item))

main.js
`
import '@/libs/requireComponents'
`
这样就相当于全局注册了,在我们需要用的地方直接使用。

require.context还有其他的用法,比如查找某个文件夹下的js文件:

const requireJs = require.context('../api', false, /\.js$/)
let fileNames = requireJs.keys();
console.log("fileNames", fileNames) 

打印:image.png

希望对还在
import from
import from
import from
import from
的同学有帮助~


前端肥智
116 声望7 粉丝

前端工程师