"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); // 所生成的所有路由数组 var Routers = []; /** * rc:require.context 传入的文件 * redirect:需要将根路由(/)重定向到的路由 * rootFile:页面级别的.vue存放的文件名称 */ exports.default = (function (config) { var defaultConfig = { rc: null, redirect: '', rootFile: 'views' }; var _a = Object.assign({}, defaultConfig, config), rc = _a.rc, redirect = _a.redirect, rootFile = _a.rootFile; if (rc === null) return Routers; // allRouters[object]:存储所有路由的变量:先将所有的路由生成,然后放在该变量里面 var allRouters = {}; // 通过循环RC(传入的文件) var routerFileAndLen = rc .keys() .map(function (fileName) { // 因为得到的filename格式是: './baseButton.vue', 所以这里我们去掉头和尾,只保留真正的文件名 var realFileName = fileName .replace(/^\.\//, '') .replace(/\.\w+$/, ''); return { fileName: realFileName, // routerName(路由名称):将 / 转为 - 并去掉 _ routerName: realFileName.replace(/\//g, '-').replace(/_/g, ''), // routerComponent(路由异步component的文件路径):将 ./baseButton.vue 从 . 之后截取 routerComponent: fileName.substr(1), // fileLen(文件的层级深度):通过 / 的数量来判断当前文件的深度 fileLen: fileName.match(/\//g).length }; }) .sort(function (i, j) { return i.fileLen - j.fileLen; }); // 通过文件深度 升序排序 // 传入文件中最大深度 var maxLen = 0; routerFileAndLen.map(function (r) { var name = r.routerName; // 生成一块路由对象,包含:name、fileName(用于后续处理真正path的依据)、path、needDelectName(用于后续处理,判断是否删除name的依据)、component var obj = { name: name, fileName: r.fileName, // path:只是以name命名的path,还不是真正的路由path path: '/' + (name === 'index' ? '' : name), // needDelectName: name === 'index', needDelectName: false, component: resolve => require.ensure([], () => resolve(require("@/" + rootFile + r.routerComponent))) }; maxLen = r.fileLen; // allRouters的key:以 'len'加当前的文件深度 作为key var key = 'len' + maxLen; if (Array.isArray(allRouters[key])) allRouters[key].push(obj); else allRouters[key] = [obj]; }); // 将根目录层的路由放入Routers中 Routers.push.apply(Routers, allRouters.len1); // 截取名称方法:从开始到最后一个'-'之间的字符串 var substrName = function (name) { return name.substr(0, name.lastIndexOf('-')); }; /** * 正式生成路由:1、将相应的路由放在对应的路由下,形成子路由;2、生成同级路由 * index:当前文件深度,为maxlen的倒序循环 * nofindnum:未找到路由的次数 * newcurr:当前新的深度下的路由数据 */ var ceateRouter = function (index, nofindnum, newcurr) { if (nofindnum === void 0) { nofindnum = 0; } if (newcurr === void 0) { newcurr = null; } // 当前深度下的路由数据:优先使用传入的newcurr,其次获取当前深度对应的路由数据 var curr = newcurr || allRouters['len' + index]; // 当前深度上一层的路由数据 var pre = allRouters['len' + (index - 1)]; // 若 没有上一层的数据了 if (!pre) { // 则表明是属于顶层的路由 curr.map(function (c) { var path = '/' + c.fileName.replace('/index', ''); if (path.match('_')) path = path.replace('/_', '/:'); // 将真正的路由path赋值给当前路由 c.path = path; // 将当前路由放到Routers里面 Routers.push(c); }); return; } // 在上一层中 未找到的 当前深度路由数据 var noFind = []; // 循环当前深度路由数据 curr.map(function (c) { // 在 上一层深度 的路由数据里面查找 var fobj = pre.find(function (p) { // 生成 当前深度 当前项 路由的name var name = substrName(c.name); // 循环nofindnum,当nofindnum>0,则表示已经出现:在上一层中未找到对应的父路由,则需要将 当前深度 当前项 路由的name 再次生成 for (var i = 0; i < nofindnum; i++) { name = substrName(name); } return name === p.name; }); // 如果 找到了 对应的 父路由数据(fobj) if (fobj) { // 生成 当前路由的path:1、去掉当前路由中与父路由重复的;2、去掉/;3、将 _ 转为 :; var path = c.fileName .replace(fobj.fileName, '') .substr(1) .replace('_', ':'); if (path.match('/') && !path.match('/:')) { path = path.replace('/index', ''); } if (path === undefined) { throw new Error("\u627E\u5230\u4E86\u5BF9\u5E94\u7684\u7236\u8DEF\u7531\uFF0C\u4F46\u662F\u751F\u6210\u5B50\u8DEF\u7531\u7684path\u4E3A\u3010undefined\u3011\u4E86"); } // 将真正的路由path赋值给当前路由 c.path = path; // 若:当前路由为 index if (path === 'index') { // 1、转为 '' path,'':表明是默认子路由,那父路由就不能存在name属性 c.path = ''; // 2、将父路由的needDelectName标记为true,表明需要删除它的name fobj.needDelectName = fobj.needDelectName || true; } // 将当前路由放到父路由的children里面 if (Array.isArray(fobj.children)) fobj.children.push(c); else fobj.children = [c]; } else noFind.push(c); // 表明未找到父路由,则先将当前路由的数据放入noFind中存储起来 }); // 若存在:未找到的路由数据,则再次向上一个层级寻找 if (noFind.length) ceateRouter(index - 1, ++nofindnum, noFind); }; // 倒序循环 最大深度,然后调用生成路由方法 for (var i = maxLen; i > 1; i--) ceateRouter(i); // 路由生成完毕了,应该删除 有默认子路由的父路由的name属性 var deleteNameFun = function (arr) { arr.map(function (r) { // 删除多余的fileName属性 delete r.fileName; // 判断是否需要删除name属性 if (r.needDelectName) delete r.name; // 判断完毕了,则要删除needDelectName属性 delete r.needDelectName; // 若 存在子路由 则继续调用deleteNameFun,删除name if (Array.isArray(r.children)) deleteNameFun(r.children); }); }; // 调用deleteNameFun,先删除Routers的一级路由的name deleteNameFun(Routers); // 若存在重定向的路由,则加入重定向 if (redirect) Routers.unshift({ path: '/', redirect: redirect }); // 返回正儿八经的的路由数据 return Routers; });