Vue/React如何优雅的一劳永逸的注册路由及组件
原文链接: 本人掘金文章 假如图片看不清晰可前往掘金原文预览
未优化版: 在Vue官方文档 中,我们通过 Vue.component('MyComponentName', { /* ... */ }) 的方式来进行全局组件注册,但如果需要全局注册的组件很多,这时代码就会变得比较臃肿,例如:
// 注册组件
import Component1 from './components/Component1'
import Component2 from './components/Component2' // 方式1
Vue.component('Component1', Component1)
Vue.component('Component2', Component2) // 方式2
const components = {
Component1,
Component2
}
Object.keys(components).forEach(key => {
Vue.component(key, components[key])
}) // 注册路由
export default new Router({
routes: [
{ // 登录页
path: '/',
name: 'Login',
component: (resolve) => { require(['@/pages/Login'], resolve) }
}]
})
优化版: webpack 提供的API神器 require.context() 可用来创建自己的(模块)上下文,具体打印看末尾
require.contex t函数接收三个参数:
- 要搜索的文件夹目录
- 是否还应该搜索它的子目录
- 以及一个匹配文件的正则表达式
一、先把我的目录结构及文件组成贴出来 (这是vue3.0未使用typescript的版本)

接下来如何自动注册组件呢: 全局新建一个 utils目录下新建一个 global.js
// 获取所有vue文件
function getComponent() {
return require.context('../views', true, /\.vue$/);
}
// 首字母转换大写
function viewToUpperCase(str) {
return str.charAt().toUpperCase() + str.slice();
}
// 首字母转换小写
function viewToLowerCase(str) {
return str.charAt().toLowerCase() + str.slice();
}
// 自动注册组件方法
export const vueComponent = () => {
// 获取文件全局对象
const requireComponents = getComponent();
requireComponents.keys().forEach((fileSrc) => {
const fileName = requireComponents(fileSrc);
const file = fileName.default;
const componentName = file.name;
// 是否自动注册组件依据每个文件里的 isComponent 属性 避免注册不用的组件
if (file.isComponent) Vue.component(componentName, fileName.default || fileName);
});
}; // 自动注册路由方法
export const vueRouters = () => {
const routerList = [];
const requireRouters = getComponent();
requireRouters.keys().forEach((fileSrc) => {
// 获取 components 文件下的文件名
const viewSrc = requireRouters(fileSrc);
console.log(viewSrc);
const file = viewSrc.default;
// 首字母转大写
const vueRouterUpper = viewToUpperCase(file.name);
// 首字母转小写
const vueRouterLower = viewToLowerCase(file.name);
const fileNameSrc = fileSrc.replace(/^\.\//, '');
// 是否自动注册路由依据每个文件里的 isRouter 属性 避免注册不用的路由
if (file.isRouter) {
// 注册路由
routerList.push({
path: `/${vueRouterLower}`,
name: `${vueRouterUpper}`,
component: () => import(`@/views/${fileNameSrc}`),
});
}
});
console.log(routerList);
return routerList;
};
引入方式


二、这是 vue3.0 使用t ypescript 的版本, 不同的是 下 global.ts 需要增加类型,及文件设置属性的方法不用, 且获取上下文的时候是在 options 里
global.ts 修改为
import Vue from 'vue'; // 获取所有vue文件
function getComponent() {
return require.context('../views', true, /\.vue$/);
}
// 首字母转换大写
function viewToUpperCase(str: string) {
return str.charAt().toUpperCase() + str.slice();
}
// 首字母转换小写
function viewToLowerCase(str: string) {
return str.charAt().toLowerCase() + str.slice();
}
export const vueComponent = () => {
// 获取文件全局对象
const requireComponents = getComponent();
requireComponents.keys().forEach((fileSrc: string) => {
const fileName = requireComponents(fileSrc);
const file = fileName.default.options;
const componentName = file.name;
if (fileName.default.isComponent) { Vue.component(componentName, fileName.default || fileName) };
});
};
// 获取路由文件
export const vueRouters = () => {
const routerList: any = [];
const requireRouters = getComponent();
requireRouters.keys().forEach((fileSrc: string) => {
// 获取 components 文件下的文件名
const viewSrc = requireRouters(fileSrc);
console.log(viewSrc);
const file = viewSrc.default.options;
// 首字母转大写
const vueRouterUpper = viewToUpperCase(file.name);
// 首字母转小写
const vueRouterLower = viewToLowerCase(file.name);
// 设置路由路劲
const fileNameSrc = fileSrc.replace(/^\.\//, '');
// 是否自动注册路由依据每个文件里的 isRouter 属性 避免注册不用的路由
if (viewSrc.default.isRouter) {
// 注册路由
routerList.push({
path: `/${vueRouterLower}`,
name: `${vueRouterUpper}`,
component: () => import(`@/views/${fileNameSrc}`),
});
}
});
console.log(routerList);
return routerList;
};
vue 文件修改为
<script lang="ts">
import Button from '@/components/Button.vue';
import { Component, Prop, Vue } from 'vue-property-decorator';
@Component({
name: 'About',
components: { Button },
})
export default class About extends Vue {
static isRouter = true; // tslint:disable-line
static isComponent = true; // tslint:disable-line
private handleClick() {
console.log('button');
}
}
</script>
require.context() 获取文件对象:
1. javascript
2. typescript 版本
react 版本不同的只是 模板文件不同,有需要的朋友可以留言我
有不对之处及有更好的方法欢迎留言指正
Vue/React如何优雅的一劳永逸的注册路由及组件的更多相关文章
- 手把手教你使用Vue/React/Angular三大框架开发Pagination分页组件
DevUI是一支兼具设计视角和工程视角的团队,服务于华为云DevCloud平台和华为内部数个中后台系统,服务于设计师和前端工程师.官方网站:devui.designNg组件库:ng-devui(欢迎S ...
- 干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)
双十一剁手节过去了,大家应该在很多网页中看到了数字翻牌的效果吧,比如倒计时. 数字增长等.相信很多人都已经自己独立实现过了,我也在网上看了一些demo,发现HTML结构大多比较复杂,用了4个并列的标签 ...
- 从DOM操作看Vue&React的前端组件化,顺带补齐React的demo
前言 接上文:谈谈我对前端组件化中“组件”的理解,顺带写个Vue与React的demo 上次写完博客后,有朋友反应第一内容有点深,看着迷迷糊糊:第二是感觉没什么使用场景,太过业务化,还不如直接写Vue ...
- vue,react,angular三大web前端流行框架简单对比
常用的到的网站 vue学习库: https://github.com/vuejs/awesome-vue#carousel (json数据的格式化,提高本地测试的效率) json在线编辑: http: ...
- 2015前端各大框架比较(angular,vue,react,ant)
前端流行框架大比拼 angular vue react ant-design angularjs angular是个MVVM的框架.针对的是MVVM这整个事.angular的最主要的场景就是单页应用, ...
- 前端开发组件化设计vue,react,angular原则漫谈
前端开发组件化设计vue,react,angular原则漫谈 https://www.toutiao.com/a6346443500179505410/?tt_from=weixin&utm_ ...
- 技能get,React的优雅升级!
今日,我们不啖鸡汤,不饮鸡血 只有干货——关于React的优雅升级 双手奉上,来,干了! -2019年第4期- 夫 子 说 本次升级基础包情况:react 15.6 -> 16.6 升级流程: ...
- 三种Web前端框架比较与介绍--Vue, react, angular
一.Angular 1.MVVM(Model)(View)(View-model): 2.模块化(Module)控制器(Contoller)依赖注入: 3.双向数据绑定:界面的操作能实时反映到数据,数 ...
- 谈谈Vue/React中的虚拟DOM(vDOM)与Key值
谈谈Vue/React中的虚拟DOM(vDOM)与Key值 一.DocumentFragment 在了解虚拟DOM前,先来了解DOM的一个对象属性--DocumentFragment. 在一次操作中, ...
随机推荐
- SonarQube规则之坏味道类型
1.Abbreviation As Word In Name (默认 关闭)坏味道 主要检查验证标识符名称中的缩写(连续大写字母)长度,还允许执行骆驼案例命名allowedAbbreviationLe ...
- Eclipse 中的 parameter参数,property属性,preference首选项 区别
parameter参数 1.配置框架 web.xml <init-param> <param-name>contextConfigLocation</param-name ...
- [CERC2016]:凸轮廓线Convex Contour(模拟+数学)
题目描述 一些几何图形整齐地在一个网格图上从左往右排成一列.它们占据了连续的一段横行,每个位置恰好一个几何图形.每个图形是以下的三种之一:$1.$一个恰好充满单个格子的正方形.$2.$一个内切于单个格 ...
- 利用python进行数据分析--pandas入门1
随书练习,第五章 pandas入门1 # coding: utf-8 # In[1]: from pandas import Series, DataFrame # In[2]: import pa ...
- 【30分钟学完】canvas动画|游戏基础(2):从零开始画画
前言 上篇主要是理论的概述,本篇会多些实践,来讲讲canvas的基础用法,并包含一些基础三角函数的应用,推荐没有canvas基础的朋友阅读,熟悉的朋友可以跳过. 本人能力有限,欢迎牛人共同讨论,批评指 ...
- php 判断访问是否是手机或者pc
php代码 function isMobile() { $user_agent = $_SERVER['HTTP_USER_AGENT']; $mobile_agents = Array(" ...
- iOS即时通讯之CocoaAsyncSocket源码解析四
原文 前言: 本文为CocoaAsyncSocket源码系列中第二篇:Read篇,将重点涉及该框架是如何利用缓冲区对数据进行读取.以及各种情况下的数据包处理,其中还包括普通的.和基于TLS的不同读取操 ...
- nginx 入门 安装
.yum解决编译nginx所需的依赖包,之后你的nginx就不会报错了 yum install gcc patch libffi-devel python-devel zlib-devel bzip2 ...
- EDM营销应注意要定期发送邮件
一个成熟的EDM营销方案应该要确定完整的邮件发送频率,并且严格按照计划执行.这点在EDM营销过程中非常重要,下面为大家分析一下. 一个EDM营销应该确定一下发送的时间,每月或者每周发送一次,这样用户能 ...
- 阶段1 语言基础+高级_1-3-Java语言高级_03-常用API第二部分_第5节 StringBuilder类_1_StringBuilder的原理
字符串不可变.字符串的缓冲区是可以变的 字符串Sting的底层,被final修饰的不可变的数组 a+b+c最终会产生5个字符串