如果使用了Webpack进行了文件的组织、编译,就可以使用require.context
令组件实现自动化注册。
这个过程需要在创建Vue实例之前(new Vue({})
)之前完成,例如src/main.js
require.context
Webpack解析带有表达式的require
语句时,会创建一个上下文(context
),因为在编译时(compile time)并不清楚具体是哪一个模块被导入。
上下文模块还包含一些运行时(runtime)逻辑来访问这个map
对象。
这意味着Webpack能够支持动态require
,但会导致所有可能用到的模块都包含在bundle
中。
还可以使用require.context()
方法来创建自己的(模块)上下文。
你可以给这个方法传3个参数:要搜索的文件夹目录,是否还应该搜索它的子目录,以及一个匹配文件的正则表达式。
语法如下:
1
| require.context(directory, useSubdirectories = false, regExp = /^\.\//);
|
实例:
1 2 3 4 5
| require.context('./test', false, /\.test\.js$/);
require.context('../', true, /\.stories\.js$/);
|
传递给 require.context 的参数必须是字面量(literal)!
导出的上下文有是三个属性:
resolve
是一个函数,它返回请求被解析后得到的模块id。
keys
也是一个函数,它返回一个数组,由所有可能被上下文模块处理的请求组成
id
是上下文模块里面所包含的模块id
==用自己创建出的上下文,去引入要引入的文件,这是关键==:
1 2
| const context = require.context('.', false, /.*\.(jpg|png)$/); const images = context.keys().map(v => context(v));
|
利用require.context
注册组件
在main.js
中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| const requireComponent = require.context( './components', false, /Base[A-Z]\w+\.(vue|js)$/ )
requireComponent.keys().forEach(fileName => { const componentConfig = requireComponent(fileName)
const componentName = upperFirst( camelCase( fileName.replace(/^\.\/(.*)\.\w+$/, '$1') ) )
Vue.component( componentName, componentConfig.default || componentConfig ) })
|
动态注册路由
实现组件的自动注册后就可以实现路由的自动注册,在router/index.js
中
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| import Vue from 'vue'; import Router from 'vue-router';
const requireComponent = require.context('../components/demos', true, /demo[1-9][0-9]?\.vue$/); const routes = requireComponent.keys().map(fileName => { const componentConfig = requireComponent(fileName);
const componentName = fileName.replace(/^\.\/(demo[1-9][0-9]?).*\.\w+$/, '$1');
const component = Vue.component( componentName, componentConfig.default || componentConfig ); return { path: `/${componentName}` , name: componentName, component, } });
Vue.use(Router);
export default new Router({ routes, })
|
动态导出/引入文件
脱离Vue,在使用Webpack的一般情况下也可以通过require
来导出和引入组件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| const context = require.context('./', false, /Demo\d+\.js$/);
const Demos = context.keys().reduce((total, current) => { const name = current.replace(/^\.\/(Demo\d+).*\.\w+$/, '$1'); total[name] = context(current).default; return total }, {});
export default Demos;
import DEMOS from './demos/' const { Demo01, Demo02 } = DEMOS;
|
注意,由于Demo
是通过default
导出的,所以需要使用.default
来获取模块
其他应用
还可以使用require.context
实现一些其他目录的操作,例如读取目录下的图片:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| <template> <div> <img v-for="img in images" :src="img" :key="img" class="insert"> </div> </template>
<script> const context = require.context('.', false, /.*\.(jpg|png)$/); const images = context.keys().map(v => context(v)); export default { data() { return { images, } } } </script>
|
参考