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. 在一次操作中, ...
随机推荐
- IE等浏览器兼容问题解决方案
<meta http-equiv="X-UA-Compatible" content="IE=100" /> 在<head>标签中添加.
- [CF Round603 Div2 F]Economic Difficulties
题目:Economic Difficulties 传送门:https://codeforces.com/contest/1263/problem/F 题意:给了两棵tree:Ta(拥有a个节点,节点编 ...
- MySQL Password Expired
好久没有登录MySQL,登录的时候遇到如下提示: 尝试使用命令行登录,发现是可以使用之前的密码登录的,如下: 只是登录之后,发现做不了什么操作.并且使用,alter 语句重设密码也没有成功,如下: 试 ...
- PHP代码修改后提交,无法立即生效
今天遇到一个坑爹的问题,就是我修改了PHP代码,提交到网站根目录以后,刷新浏览器居然无法立即生效,差不多得一分钟的样子再去刷新,才会看到更改后的效果. 出现这个问题的原因,是因为手头的项目需要较高的P ...
- SSH 连接慢 等好久
SSH连接慢,要等好久好久,有时出现输入密码提示符,输入密码回车立即就超时了. ssh -v xxx.xxx.xxx.xxx 看到是GSS的问题. 解决办法,在两边SSH上配置,UseDNS如果被 ...
- cenos 7 中firewalld开放服务端口
转载 CentOS 7 为firewalld添加开放端口及相关资料 1.运行.停止.禁用firewalld 启动:# systemctl start firewalld 查看状态:# syste ...
- vue +ts 在router的路由中import报错的解决方案
在router.ts中引入.vue文件,会提示打不到module,但是编译可能成功,运行也不报错 找了好久,发现了这个答案 https://segmentfault.com/a/11900000167 ...
- (转)IDataGridViewEditingControl 接口 作用
本文转载自:http://blog.csdn.net/zx13525079024/article/details/4814575 IDataGridViewEditingControl 接口 定义承载 ...
- Non-local Neural Networks
1. 摘要 卷积和循环神经网络中的操作都是一次处理一个局部邻域,在这篇文章中,作者提出了一个非局部的操作来作为捕获远程依赖的通用模块. 受计算机视觉中经典的非局部均值方法启发,我们的非局部操作计算某一 ...
- java将url里面的中文改成ASCII字符集 和 SCII字符集 改成 中文
package com.example.demo; import java.io.UnsupportedEncodingException; import java.net.URLDecoder; / ...