vue 自动注入路由、公共组件
# vue 自动注入路由、公共组件
vue 自动注入路由文件、全局公共组件
# 文件目录结构
- 一般采用 vue/cli 脚手架构建项目时
- 将项目路由页面文件放在 src/views 文件夹中
- src/views 文件夹下放置项目主要的几个文件 如 登录页(Login.vue) 项目主入口页(Home.vue) 以及路由跳转分发中心(routerCenter.vue 注:主要是为了在路由跳转是添加动画效果而加上的这个页面,可以忽略不写这个页面)
- 然后在 src/views 下面新增功能页面文件夹 pages
- 在 src/views/pages 文件夹下放置项目各模块代码文件
- components 文件夹下放置全局公共组件
# 全局公共组件自动注入
# 配置全局组件文件识别并载入
// 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;