template-market项目

135 阅读3分钟

require.context

require.context是什么

  require.context是webpack中的一个api,通过执行这个api会返回一个特定的上下文(一个对象里面保存了很多有用的状态),主要用来实现自动化导入模块,在前端工程中,如果遇到从一个文件夹中引入很多模块的情况,可以使用这个api,它会遍历文件夹中指定文件然后自动导入上下文,使得不需要每次都要显式的调用import导入模块.import是导入文件,require.context是导入模块中匹配的所有文件.

require.context介绍

  require.context接受三个参数

  • directory {String} -读取文件的路径
  • useSubdirectories {Boolean} -是否遍历文件的子目录
  • regExp {RegExp} -匹配文件的正则 例子:
require.context('./test', false, /.test.js$/);

  上面代码的意思是遍历test文件夹下的所有匹配以.test.js结尾的文件,不遍历子项目.

    调用require.context('./test', false, /.test.js$/)会得到test文件夹下文件的执行环境也就是上下文,里面包含了文件的有用信息.值得注意的是require.context函数执行后返回的上下文包含三个属性:

  • resolve {Function} -接受一个参数request,request为test文件夹下面匹配文件的文件名,返回这个匹配文件相对于整个工程的相对路径
  • keys {Function} -返回匹配成功模块的名字组成的数组
  • id {String} -执行环境的id,返回的是一个字符串,主要用在module.hot.accept,应该是热加载 这三个都是作为函数的属性(注意是作为函数的属性,函数也是对象,有对应的属性).

  注意require.context函数执行后返回的上下文函数也接受一个req参数,这个参数和resolve方法的参数是一样的,即匹配文件名的文件名,执行之后就表示导入这个模块,等同于import,并且会返回一个模块数据.

上代码,如图:

51620965438_.pic_hd.jpg

import Vue from 'vue'
import moduleImport from '../components/CommitResult/commitFail.vue'

function capitalizeFirstLetter(string) {
  return string.charAt(0).toUpperCase() + string.slice(1)
}

const requireComponent = require.context(
  '../components/CommitResult', false, /\.vue$/
)

requireComponent.keys().forEach(fileName => {
  const componentConfig = requireComponent(fileName)

  const componentName = capitalizeFirstLetter(
    fileName.replace(/^\.\//, '').replace(/\.\w+$/, '')
  )

  Vue.component(componentName, componentConfig.default)
})
console.dir(requireComponent)
console.log('requireComponent', requireComponent)
console.log('keys', requireComponent.keys())
console.log('id', requireComponent.id)
console.log('resolve', requireComponent.resolve(requireComponent.keys()[0]))
console.log('module', requireComponent(requireComponent.keys()[0]))
console.log('moduleImport', moduleImport)

61620965439_.pic_hd.jpg

  总结:console.dir可以打印这个对象的属性和值,只有一个参数,console.log是直接打印这个对象,可以传两个参数,module和moduleImport都表示导入这个模块.简单来说require.context函数接受三个参数,执行之后返回的函数体包含三个属性,这个函数体也可以接受一个参数,这个参数是匹配文件的文件名,执行就表示引入这个模块,等同于import,返回的是模块数据.

参考文章:www.cnblogs.com/cangqinglan…

使用场景

引入svg
import Vue from 'vue'
import SvgIcon from '@/components/svgIcon'
Vue.component('svg-icon', SvgIcon)
const req = require.context('./svg', false, /\.svg$/)
const requireAll = requireContext => requireContext.keys().forEach(requireContext)
requireAll(req)

参考文章:juejin.cn/post/684490…

全局注册组件
import Vue from 'vue'
import moduleImport from '../components/CommitResult/commitFail.vue'

function capitalizeFirstLetter(string) {
  return string.charAt(0).toUpperCase() + string.slice(1)
}

const requireComponent = require.context(
  '../components/CommitResult', false, /\.vue$/
)

requireComponent.keys().forEach(fileName => {
  const componentConfig = requireComponent(fileName)

  const componentName = capitalizeFirstLetter(
    fileName.replace(/^\.\//, '').replace(/\.\w+$/, '')
  )

  Vue.component(componentName, componentConfig.default)
})
注册路由

www.jianshu.com/p/6bf6b6a80…

样式选择器

如果你希望 scoped 样式中的一个选择器能够作用得“更深”,例如影响子组件,你可以使用 >>> 操作符,有些像 Sass 之类的预处理器无法正确解析 >>>。这种情况下你可以使用 /deep/,但是有些开发者反应,在vue-cli3编译时,deep的方式会报错或者警告。此时我们可以使用第三种方式::v-deep。通过 v-html 创建的 DOM 内容不受 scoped 样式影响,但是你仍然可以通过深度作用选择器来为他们设置样式。