在vue里,会出现很多文件引入的情况。常见的就是在router或者公共组件的引用,我们分别对这两种情况进行讨论,并提出优化方式。
一.router文件的引入
当我们的项目体系足够大时,将路由全都放在index.js文件是不优雅的,页面代码过于复杂会造成阅读和维护的困难。所以这个时候,我们一般采取分模块引用,一个模块对应一个js文件,里面存放对应的路由信息。但是当我们的模块足够多时,重复的文件引入对我们来说也是一个困扰,所以就可以使用动态引入。
我们简单写几个文件为例。上面的文件除了index.js外分别对应不同模块,我们需要动态的将几个模块自动引入到index.js里面。
require.context
require.context
是webpack提供的一个方法,可以获取一个特定的上下文。
该方法有三个参数(必填):
参数一:读取文件的路径(. 或者./表示同级)
参数二:是否遍历文件的子目录(默认false)
参数三:匹配文件的正则(注意会匹配到自己)
返回值为一个函数,函数有三个属性
属性一(Function): resolve(req) 接受一个参数request,request为test文件夹下面匹配文件的相对路径,该函数返回一个对象,对象里面的default属性代表相对路径下的文件信息。
返回这个匹配文件相对于整个工程的相对路径,参数req为keys方法返回的数组的元素
属性二(Function):keys() 返回匹配成功模块的名字组成的数组
属性三(String): id
了解了该方法后我们就可以进行文件的动态引入了。
//创建一个路由数组
let routerList = []
//获取该方法返回值,主要使用返回值的属性1和属性2
const requireAll = require.context('.', true, /\.js/)
//创建一个引入路由的动态方法
function importAllRouter(r) {
//使用属性2获取对应文件的相对路径
r.keys().forEach(item => {
//排除index.js文件
if(item !== './index.js') {
if(Array.isArray(r(key).default)) {
routerList = routerList.concat(r(key).default)
}else {
routerList.push(r(key).default)
}
}
})
}
上面的代码有些地方可能难以理解,我们详细解释下:
r(key)
使用了require.context
返回值的属性1,我们可以拿到路径匹配的文件对象
这里我们会发现我们进行了数组判断,是因为在路由文件里有时候可能一个文件就只有一个路由对象,其余的都是子路由,所以直接使用了对象格式
但是有的时候会有多个平级路由,所以得使用数组格式
其实这个可以做个简单统一,统一使用数组可以取消判断。
r(key).default
获取到的就是我们的路由文件里面的数据
最后我们将路由直接引入
const router = new VueRouter({
routes: [...routerList]
})
二.公共组件的动态引入
项目里面的公共组件过多时,我们也可以使用上面的方法进行动态引入。
例如我们有以下几个公共组件
想要进行动态引入我们需要使用插件形式进行操作
在src下面新建文件 importModul.js
const install = function (Vue) {
const requireAll = require.context('@/views/modulUnifiedIn/components', true, /\.vue/)
const modulList = requireAll.keys().map(item => requireAll(item))
modulList.forEach(({
default: modulObj
}) => {
Vue.component(modulObj.name, modulObj)
});
}
export default install
插件形式可以是名为install的函数或者是包含install属性,属性值为函数的对象,我们这里直接使用install函数的形式。
逻辑大概与上面的路由引入一致,Vue.component
可以进行组件的注册操作。
最后直接引用插件进行注册使用即可。
import importModulfrom './importModul'
Vue.use(importModul)