原文链接: 本人掘金文章  假如图片看不清晰可前往掘金原文预览

官方文档: 组建注册 路由注册

未优化版: 在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函数接收三个参数:

  1. 要搜索的文件夹目录
  2. 是否还应该搜索它的子目录
  3. 以及一个匹配文件的正则表达式

一、先把我的目录结构及文件组成贴出来 (这是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如何优雅的一劳永逸的注册路由及组件的更多相关文章

  1. 手把手教你使用Vue/React/Angular三大框架开发Pagination分页组件

    DevUI是一支兼具设计视角和工程视角的团队,服务于华为云DevCloud平台和华为内部数个中后台系统,服务于设计师和前端工程师.官方网站:devui.designNg组件库:ng-devui(欢迎S ...

  2. 干货满满!如何优雅简洁地实现时钟翻牌器(支持JS/Vue/React)

    双十一剁手节过去了,大家应该在很多网页中看到了数字翻牌的效果吧,比如倒计时. 数字增长等.相信很多人都已经自己独立实现过了,我也在网上看了一些demo,发现HTML结构大多比较复杂,用了4个并列的标签 ...

  3. 从DOM操作看Vue&React的前端组件化,顺带补齐React的demo

    前言 接上文:谈谈我对前端组件化中“组件”的理解,顺带写个Vue与React的demo 上次写完博客后,有朋友反应第一内容有点深,看着迷迷糊糊:第二是感觉没什么使用场景,太过业务化,还不如直接写Vue ...

  4. vue,react,angular三大web前端流行框架简单对比

    常用的到的网站 vue学习库: https://github.com/vuejs/awesome-vue#carousel (json数据的格式化,提高本地测试的效率) json在线编辑: http: ...

  5. 2015前端各大框架比较(angular,vue,react,ant)

    前端流行框架大比拼 angular vue react ant-design angularjs angular是个MVVM的框架.针对的是MVVM这整个事.angular的最主要的场景就是单页应用, ...

  6. 前端开发组件化设计vue,react,angular原则漫谈

    前端开发组件化设计vue,react,angular原则漫谈 https://www.toutiao.com/a6346443500179505410/?tt_from=weixin&utm_ ...

  7. 技能get,React的优雅升级!

    今日,我们不啖鸡汤,不饮鸡血 只有干货——关于React的优雅升级 双手奉上,来,干了! -2019年第4期- 夫 子 说 本次升级基础包情况:react 15.6 -> 16.6 升级流程: ...

  8. 三种Web前端框架比较与介绍--Vue, react, angular

    一.Angular 1.MVVM(Model)(View)(View-model): 2.模块化(Module)控制器(Contoller)依赖注入: 3.双向数据绑定:界面的操作能实时反映到数据,数 ...

  9. 谈谈Vue/React中的虚拟DOM(vDOM)与Key值

    谈谈Vue/React中的虚拟DOM(vDOM)与Key值 一.DocumentFragment 在了解虚拟DOM前,先来了解DOM的一个对象属性--DocumentFragment. 在一次操作中, ...

随机推荐

  1. SQL server 表copy 到别一张表

    SQL server  表copy 到别一张表 ------------------ INSERT INTO  表名 (表字段)   SELECT  表1字段 FROM 表名2: ---------- ...

  2. SQL的七种连接

    book表: t_book表: 一:inner join  AB共有的. select * from book inner join t_book on book.t_id=t_book.t_id 查 ...

  3. mysql Update语句 语法

    mysql Update语句 语法 作用:用于修改表中的数据.广州大理石机械构件 语法:UPDATE 表名称 SET 列名称 = 新值 WHERE 列名称 = 某值 mysql Update语句 示例 ...

  4. wxy和zdy眼中的水题 地精部落 dp

    题目描述 传说很久以前,大地上居住着一种神秘的生物:地精. 地精喜欢住在连绵不绝的山脉中.具体地说,一座长度为 N 的山脉 H可分 为从左到右的 N 段,每段有一个独一无二的高度 Hi,其中Hi是1到 ...

  5. noi 1700 + 1756 八皇后问题 x

    1700:八皇后问题 总时间限制:  10000ms 内存限制:  65536kB 描述 在国际象棋棋盘上放置八个皇后,要求每两个皇后之间不能直接吃掉对方. 输入 无输入. 输出 按给定顺序和格式输出 ...

  6. Nginx与Lua开发

    1.Lua及基础语法 Nginx与Lua环境 场景:用Nginx结合Lua实现代码的灰度发布 1.Lua 是一个简洁.轻量.可扩展的脚本语言 2.Nginx+Lua优势 充分的结合Nginx的并发处理 ...

  7. 170815-关于Filter的知识点

    Filter简介:         Filter翻译为中文是过滤器的意思.         Filter是JavaWeb的三大web组件之一:Servlet.Filter.Listener       ...

  8. 微信小程序之登录用户不是该小程序的开发者

    当uniapp项目转为小程序项目的时候,预览会显示“您不是登录用户...”,所以没有办法发布,这个时候打开“project.config.json”设置一下appid,与你公众号appid一致就可以

  9. 5-2 Django的路由层(urlconf) 2

    django2.0版的path 思考情况如下: urlpatterns = [ re_path('articles/(?P<year>[0-9]{4})/', year_archive), ...

  10. 一台电脑多个git使用 push 时候出现denied

    http://my.oschina.net/silentboy/blog/220158 当一台电脑上多个git account 的时候, 出现如下问题, $ git push origin maste ...