接上一篇:自动化导入vuex中JS文件

741 阅读3分钟

如果将每个不同功能的vuex对象放入modules中需要先创建文件,导出文件,再导入文件并写在modules中,这样如果文件多了每次都要重复这些步骤会很麻烦, 我想每次都自动导入modules文件夹下的js文件到index.js中,并写到modules对象中

可以通过node的方式实现自动化导入
node中有个require方法,打印这个require,控制台输出个方法

ƒ webpackEmptyContext(req) {
  var e = new Error("Cannot find module '" + req + "'");
  e.code = 'MODULE_NOT_FOUND';
  throw e;
}

require有个context方法打印console.log(require.context);,输出undefined
但是打印console.log(require.context())他会报错,说不是个方法,不过传个参数后他又有东西了console.log(require.context('./modules'))(表示modules文件夹下),输出

ƒ webpackContext(req) {
  var id = webpackContextResolve(req);
  return __webpack_require__(id);
}

继续写入第二,三个参数console.log(require.context('./modules',false,/\.js$/))(第一个参数:哪个文件目录下, 第二个参数:是否找子目录, 第三个参数:正则表达式)/\.js$/表示只找js文件,\表示转义符,正则中.有特殊含有,加个\转义一下,告诉他只是一个普通的.

打印结果还是上面那个函数,将表达式声明一个变量存着,打印这个变量

let files=require.context('./modules',false,/\.js$/)
 console.log(files);

结果还是不变,不过当打印Object.keys(files)

let files=require.context('./modules',false,/\.js$/)
console.log(Object.keys(files));

打印结果["keys", "resolve", "id"],我们需要用到keys
打印console.log(files.keys);输出

ƒ webpackContextKeys() {
  return Object.keys(map);
}

他是一个方法,继续打印console.log(files.keys())输出
["./category.js", "./order.js", "./user.js"]

这就获得了modules中拆分出去的JS文件路径,遍历这个数组得到以下结果

files.keys().forEach(item => {
    console.log(item);
});
// ./category.js
// ./order.js
// ./user.js

我们只想得到文件名不想要前后缀,使用正则来解决

files.keys().forEach(item => {
      console.log(item.match(/\.\/(.*)\.js/)[1]);
});
//category
// order
//user

这里最好用reduce方法,直接将这些方法写入modules方法中

let modules =files.keys().reduce((res,modulePath) => {
      //res初始为一个空对象,modulePath是files.keys()里每一个值
      let moduleName=modulePath.match(/\.\/(.*)\.js/)[1]
      //将模块路径名只保留名著中不带前后缀
      res[moduleName]=files(modulePath)
      //将三个文件对应的方法一一赋值,这里如果打印files('./category.js')结果就是这个文件下单个vuex对象
      return res
 //res一开始是个空对象,最后以文件名:对应方法形式合并在res这个对象中,所以return出去
},{});

console.log(modules); 结果就是想要的,但下面打印结果多套了一层dafault

let modules =files.keys().reduce((res,modulePath) => {
      let moduleName=modulePath.match(/\.\/(.*)\.js/)[1]
      let value =files(modulePath).default
      if (value) {
           res[moduleName]=value
      }     
      return res 
},{});

这样,在modules中有各自对应的对象,把代码拆分了,以后只要在modules文件夹下有js文件,就会自动导入不同模块的vuex文件

let files=require.context('./modules',false,/\.js$/)
// console.log(files.keys()); ["./category.js", "./order.js", "./user.js"]
let modules =files.keys().reduce((res,modulePath) => {
      let moduleName=modulePath.match(/\.\/(.*)\.js/)[1]
      let value =files(modulePath).default
      if (value) {
           res[moduleName]=value
      }     
      return res //res一开始是个空对象,最后以文件名:对应方法形式合并在res这个对象中,所以return出去
},{});
const store = new Vuex.Store({  
      modules
})

当然路由也可以以这种方式自动导入!只需要简单改改

let files=require.context('./modules',false,/\.js$/)
let routes =files.keys().reduce((res,modulePath) => {
      //let moduleName=modulePath.match(/\.\/(.*)\.js/)[1]
      //routes对应的是数组,不需要名字
      let value =files(modulePath).default
      if (value) {
           res.push(...value)
      }     
      return res //res一开始是个空对象,最后以文件名:对应方法形式合并在res这个对象中,所以return出去
},[]);
const router = new VueRouter({  
      routes
})

modules文件夹目录下有js文件就会自动导入,这样配置路由时可根据不同板块自由拆分路由,但这样得到的数组里不是按顺序得到的,可在路由的meta中定义个属性如sort:1,按想展示的路由前后自定义顺序,即

let files=require.context('./modules',false,/\.js$/)
let routes =files.keys().reduce((res,modulePath) => {
      //let moduleName=modulePath.match(/\.\/(.*)\.js/)[1]
      //routes对应的是数组,不需要名字
      let value =files(modulePath).default
      if (value) {
           res.push(...value)
      }     
      return res //res一开始是个空对象,最后以文件名:对应方法形式合并在res这个对象中,所以return出去
},[]);
routes.sort((a,b)=>{
       return a.meta.sort - b.meta.meta.sort
})
const router = new VueRouter({  
      routes
})