vue 自动注入路由、公共组件

# vue 自动注入路由、公共组件

vue 自动注入路由文件、全局公共组件

# 文件目录结构

  1. 一般采用 vue/cli 脚手架构建项目时
  2. 将项目路由页面文件放在 src/views 文件夹中
  3. src/views 文件夹下放置项目主要的几个文件 如 登录页(Login.vue) 项目主入口页(Home.vue) 以及路由跳转分发中心(routerCenter.vue 注:主要是为了在路由跳转是添加动画效果而加上的这个页面,可以忽略不写这个页面)
  4. 然后在 src/views 下面新增功能页面文件夹 pages
  5. 在 src/views/pages 文件夹下放置项目各模块代码文件
  6. components 文件夹下放置全局公共组件

# 全局公共组件自动注入

# 配置全局组件文件识别并载入

vue 官方文档 (opens new window)

// src/lib/globalComponents.js

//自动全局注册 ./components 文件夹下的组件

//vue官方文档  https://router.vuejs.org/zh/guide/advanced/navigation-guards.html

// 引入lodash库
import _ from "lodash";

const plugins = {
  install(Vue) {
    const requireComponent = require.context(
      // 其组件目录的相对路径(组件目录相对于当前js文件的路径)
      "../components",
      // 是否查询其子目录
      false,
      // 匹配基础组件文件名的正则表达式(因此要注册为全局组件的组件名称约定很重要)
      /[A-Z]\w+\.(vue)$/
    );
    requireComponent.keys().forEach((fileName) => {
      //   console.log(fileName)  ./BaseComponentA.vue
      // 获取组件配置
      const componentConfig = requireComponent(fileName); //这里的componentConfig包含当前fileName对应组件的所有该组件信息,等于拿到了当前组件实例
      // 获取组件的 PascalCase 命名
      const componentName =
        "My" +
        _.upperFirst(
          //这里 _ 代表lodash实例对象
          _.camelCase(
            // 获取和目录深度无关的文件名
            fileName
              .split("/")
              .pop()
              .replace(/\.\w+$/, "") //将.(包括.)字符以后的字符用''代替
          )
        );

      // 全局注册组件
      Vue.component(
        componentName,
        // 如果这个组件选项是通过 `export default` 导出的,
        // 那么就会优先使用 `.default`,
        // 否则回退到使用模块的根。
        componentConfig.default || componentConfig
      );
    });
  },
};

export default plugins;

# mian.js 中引入

// src/main.js

import globelComponents from "./lib/globalComponents"; // 全局注册公共组件

Vue.use(globelComponents);

# 路由自动注入

# 配置路由文件识别并载入

// src/lib/routerLayout.js

/* 自动获取文件生成路由 */

// 引入lodash库
import _ from "lodash";

// 配置路由权重值 用来配置路由跳转动画
let num = 2;

// 局部组件数据列表 以 ***_tem.vue结尾的文件作为局部组件 根据个人习惯修改
let temArr = [];

// 路由文件数据数组 局部组件除外的.vue文件
let routerArr = [];

/*
通过require.context获取所有.vue文件名组成的列表

require.context函数接受三个参数
directory {String} -读取文件的路径
useSubdirectories {Boolean} -是否遍历文件的子目录
regExp {RegExp} -匹配文件的正则

*/
let routers = require.context("@/views/pages", true, /.*(\.vue)$/).keys();

// 遍历
routers.forEach((item) => {
  if (!/.*(_tem\.vue)$/.test(item)) {
    // 判断是否是局部组件 不是局部组件就注入路由

    //paths中存储了一个目录,二级目录,文件名 类似["system", "user", "user", "vue"]
    const paths = item.match(/[a-zA-Z]+/g);

    // 移除paths最后一项vue,剩["system", "user", "user"] 对应一级文件夹名 二级文件夹名 ... 当前文件名(最后一个)
    paths.pop();

    // 路由name
    let name = "";

    //字符串拼转大驼峰  SystemUserUser
    paths.forEach((item) => (name += _.upperFirst(item)));

    // 配置路由对象并存入数组
    routerArr.push({
      //以文件名作为路由路径
      path: "/" + paths.pop(),
      // 以 文件路径+文件名的大驼峰 为路由名称
      name: name,
      // component: resolve => require([`@/views/page${item.slice(1)}`], resolve), // 注册文件
      component: () => import(`@/views/pages${item.slice(1)}`), // 注册文件
      meta: {
        // 可以配置一些自定义参数
        hasAuthority: true, //开启权限验证
        animateNum: ++num, // 设置路由权重,用于路由过渡动画
      },
    });
    // }
  } else {
    // 局部组件不注入路由
    // 这里可以对局部组件进行一些操作
    temArr.push(item);
  }
});

export default routerArr;

# 路由文件

// src/router/index.js

import Vue from "vue";
import VueRouter from "vue-router";

// 入口文件单独注入
import Home from "@/views/Home.vue";
import Login from "@/views/Login.vue";

// 引入路由js 获取动态路由文件列表
// 路径按各自的路径 这里是 src/lib/routerLayout.js
import routerLayout from "@/lib/routerLayout";

Vue.use(VueRouter);

const routes = [
  {
    path: "/",
    name: "登录",
    component: Login,
    meta: {
      title: "",
      hasAuthority: false, // 判断是否需要权限 true 需要权限 false 不需要权限
      tx: 1, // 路由跳转动画判断条件
    },
  },
  {
    path: "/Home",
    name: "首页",
    component: Home,
    meta: {
      title: "",
      hasAuthority: false,
      tx: 2,
    },
    children: routerLayout, // 注入动态路由
  },

  // {
  //   path: "/Login",
  //   name: "Login",
  //   component: () =>
  //     import(/* webpackChunkName: "Login" */ "@/views/Login.vue"),
  //   meta: {
  //     title: "登录",
  //     tx: 1
  //   }
  // }
  // { path: "*", redirect: { path: "/404" } } // 重定向404页面

  { path: "*", redirect: { path: "/" } }, // 重定向至登录页
];

const router = new VueRouter({
  mode: "history",
  routes,
});

export default router;