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. 在一次操作中, ...
随机推荐
- 总结PHP缓存技术的多种方法
这里所说的数据缓存是指数据库查询PHP缓存机制,每次访问页面的时候,都会先检测相应的缓存数据是否存在,如果不存在,就连接数据库,得到数据,并把查询结果序列化后保存到文件中,以后同样的查询结果就直接从缓 ...
- 不同地区Android开发者使用哪些设备测试APP?
我们的团队密切关注着移动世界的趋势,以便可以提供所有有关变化的最紧密和最重要的信息.春天恰好是对app进行新一轮测试并检查其与不同Android设备兼容性如何的最佳时机.下面让我们一起来看看全世界范围 ...
- class和style绑定
在数据绑定中,一个常见需求是,将数据与元素的 class 列表,以及元素的 style 内联样式的操作绑定在一起.由于它们都是属性(attribute),因此我们可以使用 v-bind 来处理它们:只 ...
- 解决:@Auarowired为null
使用@Auarowired时程序报空指针.如图: 将private 更改为 public 即可
- CG-CTF | 综合题2
查源码发现一个文件读取:http://cms.nuptzj.cn/about.php?file=sm.txt,用它把能找到的php都读取下来 <?php if (!isset($_COOKIE[ ...
- Linux下" >/dev/null 2>&1 "详解
在学习Linux的过程中,常会看到一些终端命令或者程序中有">/dev/null 2>&1 "出现,由于已经遇到了好几次了,为了理解清楚,不妨花点时间百度或者g ...
- Linux中退出循环命令
[root@a ~]#cat break.sh #!/bin/bash while : #其中“:”表示while循环的条件永远为真的意思 do read -p "Enter a numbe ...
- kill的各种讯号?
kill 程序 不仅仅只是k掉某个进程, 她还有很多作用和用途. 其实, 这也是linux的程序的一个特点: 一个程序(很多是 命令行的程序), 除了主要的作用外, 还有很多" 重要的, 有 ...
- LongAccumulator 源码分析
LongAccumulator LongAccumulator 能解决什么问题?什么时候使用 LongAccumulator? 1)LongAccumulator 的逻辑和 LongAdder 基本类 ...
- 树的基本概念以及java实现二叉树
树具有的特点有: (1)每个结点有零个或多个子结点 (2)没有父节点的结点称为根节点 (3)每一个非根结点有且只有一个父节点 (4)除了根结点外,每个子结点可以分为多个不相交的子树. 树的基本术语 ...