在项目中,可能有许多组件有一些通用的小组件,即基础组件,如包裹了一个输入框或按钮之类的元素,这样就会导致很多组件都会有一个包含基础组件的长列表:
import BaseButton from './BaseButton.vue'
import BaseIcon from './BaseIcon.vue'
import BaseInput from './BaseInput.vue'
export default {
components: {
BaseButton,
BaseIcon,
BaseInput
}
}
页面中使用
<BaseInput
v-model="searchText"
@keydown.enter="search"
/>
<BaseButton @click="search">
<BaseIcon name="search"/>
</BaseButton>
此时,如果用的是webpack,则可以使用 require.context
只全局注册这些非常通用的基础组件。可以直接在main.js中全局注册引入。
组件结构图片: src/components/
_global.js
import Vue from 'vue'
// https://webpack.js.org/guides/dependency-management/#require-context
const requireComponent = require.context(
// Look for files in the current directory
'.',
// Do not look in subdirectories
false,
// Only include "_base-" prefixed .vue files
/_base-[\w-]+\.vue$/
)
// For each matching file name...
requireComponent.keys().forEach((fileName) => {
// Get the component config
const componentConfig = requireComponent(fileName)
// Get the PascalCase version of the component name
const componentName = fileName
// Remove the "./_" from the beginning
.replace(/^\.\/_/, '')
// Remove the file extension from the end
.replace(/\.\w+$/, '')
// Split up kebabs
.split('-')
// Upper case
.map((kebab) => kebab.charAt(0).toUpperCase() + kebab.slice(1))
// Concatenated
.join('')
// Globally register the component
Vue.component(componentName, componentConfig.default || componentConfig)
})
全局注册的行为必须在根 Vue 实例 (通过 new Vue) 创建之前发生
main.js
import '@components/_globals'
profile.vue
<BaseIcon name="user" />
require.context()
用法:
接收三个参数(require.context(directory,useSubdirectories,regExp))
directory:说明需要检索的目录
useSubdirectories:是否检索子目录
regExp: 匹配文件的正则表达式,一般是文件名
返回参数
require.context返回一个require 函数,此函数可以接收一个参数
返回的函数:function webpackContext(req) {return webpack_require(webpackContextResolve(req))};
函数有三个属性:resolve 、keys、id
resolve: 是一个函数,他返回的是被解析模块的id ,接受一个参数request。
keys: 也是一个函数,他返回的是一个数组,该数组是由所有可能被上下文模块解析的请求对象组成
id:上下文模块的id
应用实例
如果页面需要导入多个组件时,一般的写法
import aaa from '@/components/login/aaa'
import bbb from '@/components/login/bbb'
import ccc from '@/components/login/ccc'
import ddd from '@/components/login/ddd'
components:{
aaa,
bbb,
ccc,
ddd,
}
使用require.context()时的写法就简洁了许多
const path = require('path')
const files = require.context('@/components/login', false, /\.vue$/)
const modules = {}
files.keys().forEach(key => {
const name = path.basename(key, '.vue') // 提取出用 ‘/' 隔开的path的最后一部分,path.basename(p, [ext])。 p要处理的path,ext要过滤的字符
modules[name] = files(key).default || files(key)
})
components:modules
files此时是一个函数
files.keys()属性方法执行后会返回一个数组:["./aaa.vue", “./bbb.vue”, “./ccc.vue”, “./ddd.vue”]
files.resolve(’./aaa.vue’)属性方法传入一个login文件下的相对路径(’./aaa.vue’)会返回匹配到的文件的绝对路径("./src/components/login/aaa.vue")