浅入深出Vue:代码整洁之去重
在开始本篇的主题之前,让我们把上次遗留下来的问题都清理一下:
- 将其他组件中
axios请求的地方封装起来。
这里就不把代码放在开头了,相关代码都放在文末,有兴趣了解的童鞋可以先往下翻。
好了, 我们现在把上篇剩下的任务给完成了,接下来我们来正式开始本篇内容吧。
去重是什么
字面上意思:去除重复,在项目中,不可避免的会出现重复代码。但是如果不好好去处理这些重复代码,那很有可能就会给你很多“惊喜”。
如何为“重复” 下一个定义呢?
从最浅显的层次来看, 相同即是重复。在我们上面的代码中,每一个组件中都有这么一行代码:
import RequestSender from '@/requestSender';
这就是重复代码,在每一个需要发起请求的组件中你都会需要写上这么一行代码。那么让我们就这个列举一些可能出现的问题:
某一天修改了文件名
某一天移动了该文件
那么项目中需要修改的地方将会是多少呢?而在修改中会产生手误的概率又会是多少呢?以上还是在单人开发的时候,如果团队协作开发,这些情况的概率又会是什么样的呢。
如何去重
当然,对于上面这种引入型的代码,类似移动文件,修改文件名这种操作。IDE 就能很好的帮你处理,比如 WebStorm 如果你使用重构相关的功能去重命名,那么它会找出所有 “疑似”引用的代码片段,你可以选择所有相关的引用同时修改。
这是一种手段,很好的解决了上面这些问题。
那么让我们来看看另一个重复代码的问题:
class RequestSender {
static GetBlogList() {
return axios.get('https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io/list');
}
static Publish(data) {
return axios.post('https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io/publish', data);
}
static Login(data) {
return axios.post('https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io/login', data);
}
static Signup(data) {
return axios.post('https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io/signup', data);
}
}
上面的代码, 重点不在函数噢。 仔细看看它们有哪些地方重复了。
光从代码上来看,其实有很多“重复”的地方,比如说 return、static、axios.get、axios.post。
这些重复有一部分是语法,有一部分是调用。这些都是不可避免的,因此这些重复代码并不在我们需要重构的范围内。那么,究竟是哪段代码呢?
https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io
准确来说,它并不算是代码。而是“硬编码”,从整体代码上来看,这是目前所有后台接口的域名。
在开发过程中,一般来说至少是会有两个环境存在:开发环境、线上环境。而它们两的后台接口域名一般而言又不会重复,难道每次发布前都手动改一下域名么?
我们先来列举一下可能会出现的问题:
开发环境、线上环境域名不一致
团队协作中,开发者之间的开发域名不一致
当线上/开发 环境中的域名需要修改时
可以看到,当遇到上述问题时,项目中所有硬编码了域名的地方都是需要修改的,那么为什么要修改呢?
除了解决上面列举的具体问题之外,最根本的目的是:
- 保持唯一性
如果有两段/多段代码它们表示的含义完全一致,并且从目的上来说也是一致的。那么就应该尽可能将其只保留一处定义。
那么对于这个域名我们怎么处理呢?首先将其提炼出来:
static Host = 'https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io';
这样,引用的地方就可以这么写:
static GetBlogList() {
return axios.get(`${Host}/list`);
}
这样,当发现修改的时候,是不是只需要修改 Host 这么一个地方就好了呢?、
但是这样还存在问题,如果要发布,或者是在 git 、 svn上协作的时候呢? 每个人、每个环境都需要修改这个变量,并且还要在提交代码时移除掉自己的修改以避免冲突。
可配置化
Host 的例子是非常常见的,当我们需要发布、团队协作的时候,环境不同是非常常见的,有可能在自己电脑上 Host 是 localhost:8080,换在另一个人电脑上就是 localhost:9099了。那么线上环境有可能又是 xxx.xxx.com 、xx.xxx.com/api诸如此类。
这里若羽实践的解决方案是:
将与环境相关的硬编码提炼成可配置项放入配置文件
配置文件模板化
配置模板文件多样化
真正的配置文件是不会被提交上去,只有一个模板文件。由于配置文件并不会被提交,所以开发者之间的环境差异就可以忽略了,大家根据自己的环境修改配置文件即可。
那么对于线上环境、测试环境等等,建立对应的配置文件模板即可。当发布时,使用对应环境的发布配置文件模板作为配置文件即可。
那么我们来实践一下:
新建配置模板文件 config.js.template:
const config = {
HOST: '',
};
export default config;
接下来复制粘贴模板文件,并重命名为 config.js:
const config = {
HOST: 'https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io',
};
export default config;
接下来修改一下 requestSender.js:
import axios from 'axios';
import config from '@/config.js';
class RequestSender {
static GetBlogList() {
return axios.get(`${config.HOST}/list`);
}
static Publish(data) {
return axios.post(`${config.HOST}/publish`, data);
}
static Login(data) {
return axios.post(`${config.HOST}/login`, data);
}
static Signup(data) {
return axios.post(`${config.HOST}/signup`, data);
}
}
export default RequestSender;
好了,现在不管是在任何一个环境下,都可以游刃有余的切换域名了。而且这里面还有一个很有意思的事情:
- 所有的改动对于表现层而言是透明的。
简单来说,我们在这里重构了这么多的代码,然而我们并不需要修改任何一个视图组件中的代码!!!
表面上还是原来的样子,可实际上已经“打扫”过了。这也是重构中需要注意的一点:
- 步子迈小一点,迈准一点
写在后面
上篇中有人问到若羽说封装请求的意义何在,axios 本身就是带着 Promise的支持了。
这里对这个问题做一个回应,立场仅代表若羽本人,并不为任何人“做代表”:
封装并非为了
Promise,而是为了将“发送请求”的这个动作封装起来。因为这属于数据获取的行为,而后面then里的逻辑实际上是和业务挂钩:为视图设置数据。这是两个不同的行为,就像后端一样:ORM它仅仅是负责从数据库中取数据而已,真正对这个数据进行逻辑操作的,并不是它。这也是接下来博文的主题:专一,一个函数应当只负责一件事情。这一篇文章便表示了另一层意思:去重,在第一层封装的过程中我们发现了
域名的硬编码问题(不封装也是一样),因此在这里如果不做封装的话,即使将域名提炼出来,涉及到修改的文件同样也会较多。不过这种修改是一次性的。
以上便是若羽对上一篇中示例的解释。
欢迎大家发表评论,共同探讨。
上篇重构代码
edit.vue:
<script>
import RequestSender from '@/requestSender'
export default {
name: "Edit",
data() {
return {
model: {
title: '',
content: '',
}
}
},
methods: {
submit() {
RequestSender.Publish(this.model)
.then(res => {
if(res.data.Code === 200) {
this.$message.success('发布成功');
}
})
}
}
}
</script>
Login.vue:
<script>
import RequestSender from '@/requestSender';
export default {
name: "Login",
data() {
return {
model: {
username: '',
password: '',
}
}
},
methods: {
submit() {
RequestSender.Login(this.model)
.then(res => {
if(res.data.Code === 200) {
this.$message.success('登录成功');
}
})
}
}
}
</script>
Signup.vue:
<script>
import RequestSender from '@/requestSender';
export default {
name: "Signup",
data() {
return {
model: {
username: '',
password: '',
rePassword: ''
}
};
},
methods: {
submit() {
if(this.model.password !== this.model.rePassword){
this.$message.error('两次出入密码不一致.');
return ;
}
RequestSender.Signup(this.model)
.then(res => {
if(res.data.Code === 200){
this.$message.success("注册成功");
this.$router.push('./login');
}
});
}
}
}
</script>
requestSender.js:
import axios from 'axios';
class RequestSender {
static GetBlogList() {
return axios.get('https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io/list');
}
static Publish(data) {
return axios.post('https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io/publish', data);
}
static Login(data) {
return axios.post('https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io/login', data);
}
static Signup(data) {
return axios.post('https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io/signup', data);
}
}
export default RequestSender;
浅入深出Vue:代码整洁之去重的更多相关文章
- 浅入深出Vue:前言
浅入深出Vue系列文章 之前大部分是在做后端,后来出于某些原因开始接触Vue.深感前端变化之大,各种工具.框架令人眼花缭乱.不过正是这些变化,让前端开发更灵活. 博主在刚开始时,参考官网的各个步骤以及 ...
- 浅入深出Vue:工具准备之PostMan安装配置及Mock服务配置
浅入深出Vue之工具准备(二):PostMan安装配置 由于家中有事,文章没顾得上.在此说声抱歉,这是工具准备的最后一章. 接下来就是开始环境搭建了~尽情期待 工欲善其事必先利其器,让我们先做好准备工 ...
- 浅入深出Vue:环境搭建
浅入深出Vue:环境搭建 工欲善其事必先利其器,该搭建我们的环境了. 安装NPM 所有工具的下载地址都可以在导航篇中找到,这里我们下载的是最新版本的NodeJS Windows安装程序 下载下来后,直 ...
- 浅入深出Vue:工具准备之WebStorm安装配置
浅入深出Vue之工具准备(一):WebStorm安装配置 工欲善其事必先利其器,让我们先做好准备工作吧 导航篇 WebStorm安装配置 所有工具的下载地址都可以在导航篇中找到,这里我们下载的是最新版 ...
- 浅入深出Vue系列
浅入深出Vue导航 导航帖,直接点击标题即可. 文中所有涉及到的资源链接均在最下方列举出来了. 前言 基础篇 浅入深出Vue:工具准备之WebStorm搭建及配置 浅入深出Vue之工具准备(二):Po ...
- 浅入深出Vue:代码整洁之封装
深入浅出vue系列文章已经更新过半了,在入门篇中我们实践了一个小小的项目. <代码整洁之道>一书中提到过一句话: 神在细节中 这句话来自20世纪中期注明现代建筑大师 路德维希·密斯·范·德 ...
- 浅入深出Vue:第一个页面
今天正式开始入门篇,也就是实战了~ 首先我们是要做一个博客网站,UI 框架采用江湖传闻中的 ElementUI,今天我们就来利用它确定我们博客网站的基本布局吧. 准备工作 新建一个vue项目(可以参考 ...
- 浅入深出Vue:文章列表
终于到我们小项目的最后一个功能了,那就是列表页展示! 新建组件 先来新建组件 List.vue: <template> <div></div> </templ ...
- 浅入深出Vue:发布项目
项目完成之后,当然不能满足于在我们的开发环境下跑一跑.我们可以打包发布到服务器上,让大家一起来欣赏一下你的作品. 那么 vue 项目如何打包发布呢,新建的项目目录下通常都有一个 README.md 的 ...
随机推荐
- 手机软件没过多久就删了 APP到底得了什么病?
直击现场 PC互联网时代正渐行渐远,移动互联网的创业浪潮汹涌而至.2014年,中国成为拥有智能手机用户最多的国家,而疯狂生长的APP正占据新的风口.据了解,目前我国主要应用商店的APP已累计超过400 ...
- 微软Skype实时口译增加中文
直击现场 在机器翻译技术上,微软的 Skype 业务也算是行业内名列前茅.日前其实时口语翻译技术再次跃升一个台阶,新增了对中文(普通话)的翻译支持. 据美国科技新闻网站 TheVerge 报道,此前, ...
- 核心思想:自由职业的所谓自由,必须先职业,然后才能自由(还要对抗自己的惰性,提前寻找客户)good
除了前面提到的专业性,还要足够自律,能够管理好自己的时间和精力. 具体来说,需要目标管理和时间(精力)管理. 所谓目标管理,对于自由职业者来讲,就是要识别出自己最擅长的方向,确立自己可以提供的最有价值 ...
- Google+团队如何测试移动应用 - from Google Testing Blog
How the Google+ Team Tests Mobile Apps by Eduardo Bravo Ortiz “移动第一”在当下已成为很多公司的口头禅.但是能够用一种合理的方法来测试移动 ...
- RocketMQ 可视化环境搭建和基础代码使用
RocketMQ 是一款分布式消息中间件,最初是由阿里巴巴消息中间件团队研发并大规模应用于生产系统,满足线上海量消息堆积的需求, 在 2016 年底捐赠给 Apache 开源基金会成为孵化项目,经过不 ...
- MySQL下的DB Link
前言: 在实际工作中,我们可能会遇到需要操作其他数据库实例的部分表,但又不想系统连接多库.此时我们就需要用到数据表映射.如同Oracle中的DBlink一般,使用过Oracle DBlink数据库链接 ...
- 【前端优化】js图片懒加载及优化
一.前言 为啥要对图片使用懒加载?我们首先来聊聊这个问题,对于页面来说架子啊速度影响着最大的就是图片,一张普通的图片可以达到4-5M的大小,而代码压缩也就只有几十KB.当页面图片过多的时候,页面加载速 ...
- Mac上使用brew update会卡住的问题
Mac上使用brew update会卡住的问题 brew默认的源是Github,会非常慢,建议换为国内的源.推荐中科大的镜像源,比较全面. 解决方案 Homebrew Homebrew源代码仓库 替换 ...
- ZooKeeper入门(三) ZooKeeper数据模型
1 简述 ZooKeeper可以看成一种高可用性的文件系统,但是,它没有文件和目录,而是使用节点,称为znode. znode可以作为保存数据的容器(如同文件),也可以作为保存其他节点的容器(如同目录 ...
- Gym 101257B:2Trees(DFS+思维)
http://codeforces.com/gym/101257/problem/B 题意:给出两棵叶子数一样的树,在将叶子合并之后,对这个图进行染色,相邻的结点颜色不能相同,问最少需要染的颜色数,并 ...