自动化注册组件,自动化注册路由--懒人福利(vue,react皆适用)

开头

本菜鸡自从入职以来,一直在作相关的entry task,task1在上一篇文章中指出。此篇文章记录一下我在task2中的奇思妙想。vue

task2是从0到1实现一个vue2+ts的项目,说实话vue2+ts真的是难用,有没有同感的。。react

我是一个react主义者,此次由于项目组关系必须用vue,做为vue小白就记录一下开发过程当中的一些骚想法。webpack

image.png

正文

1. 对于路由的操做

可能用过umi的同窗知道,umi有一套约定式路由的系统,开发过程当中能够避免每写一个页面就去手动import到路由的数组中,你只须要按照规则,就能够自动化的添加路由。web

完美,咱们今天就简单实现一个约定式路由的功能。vue-router

首先把vue本身的路由注释掉数组

// const routes: Array<RouteConfig> = [
//   {
//     path: "/login",
//     name: "login",
//     component: Login,
//   },
//   // {
//   //   path: "/about",
//   //   name: "About",
//   //   // route level code-splitting
//   //   // this generates a separate chunk (about.[hash].js) for this route
//   //   // which is lazy-loaded when the route is visited.
//   //   component: () =>
//   //     import(/* webpackChunkName: "about" */ "../views/About.vue"),
//   // },
// ];
复制代码

能够看到代码很是的多,随着页面的增长也会愈来愈多。固然vue的这种方式也有不少好处:好比支持webpack的魔法注释,支持懒加载markdown

接下来就去实现咱们的约定式路由吧!优化

咱们此次用到的API是require.context,你们可能觉得须要安装什么包,不用不用!这是webpack的东西!具体API的介绍你们能够自行百度了ui

首先用这玩意去匹配对应规则的页面,而后提早创好咱们的路由数组以便使用。this

const r = require.context("../views", true, /.vue/);
const routeArr: Array<RouteConfig> = [];
复制代码

接下来就是进行遍历啦,匹配了../views文件下的页面,遍历匹配结果,若是是按照咱们的规则建立的页面就去添加到路由数组中

好比我如今的views文件夹里是这样的

image.png

// 遍历
r.keys().forEach((key) => {
  console.log(key) //这里的匹配结果就是 ./login/index.vue  ./product/index.vue
  const keyArr = key.split(".");
  if (key.indexOf("index") > -1) {
    // 约定式路由构成方案,views文件夹下的index.vue文件都会自动化生成路由
    // 可是我不想在路由中出现index,我只想要login,product,因而对path进行改造。
    // 这部实际上是有不少优化空间的。你们能够本身试着用正则去提取
    const pathArr = keyArr[1].split("/");
    routeArr.push({
      name: pathArr[1],
      path: "/" + pathArr[1],
      component: r(key).default, // 这是组件
    });
  }
});
复制代码

一块儿来看一下自动匹配出来的路由数组是什么模样

image.png

完美🚖达成了咱们的需求。去页面看一看!

image.png

完美实现! 最后把所有代码送上。这样就实现了约定式自动注册路由,避免了手动添加的烦恼,懒人必备

import Vue from "vue";
import VueRouter, { RouteConfig } from "vue-router";
const r = require.context("../views", true, /.vue/);
const routeArr: Array<RouteConfig> = [];
r.keys().forEach((key) => {
  const keyArr = key.split(".");
  if (key.indexOf("index") > -1) {
    // 约定式路由构成方案,views文件夹下的index.vue文件都会自动化生成路由
    const pathArr = keyArr[1].split("/");
    routeArr.push({
      name: pathArr[1],
      path: "/" + pathArr[1],
      component: r(key).default, // 这是组件
    });
  }
});
Vue.use(VueRouter);

const router = new VueRouter({
  mode: "history",
  base: process.env.BASE_URL,
  routes: routeArr,
});

export default router;
复制代码

2.组件

通过上一章的操做,咱们能够写页面了,而后就写到了组件。我发现每次使用组件都要在使用的页面去import,很是的麻烦。

image.png

经过上一章的想法,咱们是否是也能够自动化导入组件呢?

个人想法是:

  • 经过一个方法把components文件下的全部组件进行统一的管理

  • 须要的页面能够用这个方法传入对应的规则,统一返回组件

  • 这个方法能够手动导入,也能够全局挂载。

先给你们看一下个人components文件夹

image.png

再看一下如今的页面长相

image.png

ok。咱们开始在index.ts里撸代码吧

首先第一步同样的去匹配,这里只须要匹配当前文件夹下的全部vue文件

const r = require.context("./", true, /.vue/);
复制代码

而后声明一个方法,这个方法能够作到fn('规则')返回对应的组件,代码以下。

function getComponent(...names: string[]): any {
  const componentObj: any = {};
  r.keys().forEach((key) => {
    const name = key.replace(/(\.\/|\.vue)/g, "");
    if (names.includes(name)) {
      componentObj[name] = r(key).default;
    }
  });
  return componentObj;
}
export { getComponent };
复制代码

咱们一块儿来看看调用结果吧

image.png

打印结果:

image.png

看到这个结果不难想象页面的样子吧! 固然跟以前同样啦!固然实现啦!

image.png

很是的完美!

image.png

最后

因为项目比较急咯,我还有一些骚想法没有时间去整理去查资料实现,暂时先这样吧~

若是文内有错误,敬请你们帮我指出!(反正我也不必定改哈哈)

最后!谢谢!拜拜!