Vue代码整洁之去重方法整理


Posted in Javascript onAugust 06, 2019

在开始本篇的主题之前,让我们把上次遗留下来的问题都清理一下:

将其他组件中 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);
  }
}

上面的代码, 重点不在函数噢。 仔细看看它们有哪些地方重复了。

光从代码上来看,其实有很多“重复”的地方,比如说 returnstaticaxios.getaxios.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 这么一个地方就好了呢?、

但是这样还存在问题,如果要发布,或者是在 gitsvn上协作的时候呢? 每个人、每个环境都需要修改这个变量,并且还要在提交代码时移除掉自己的修改以避免冲突。

可配置化

Host 的例子是非常常见的,当我们需要发布、团队协作的时候,环境不同是非常常见的,有可能在自己电脑上 Hostlocalhost:8080,换在另一个人电脑上就是 localhost:9099了。那么线上环境有可能又是 xxx.xxx.comxx.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代码整洁之去重的相关知识点,感谢大家的阅读和对三水点靠木的支持。

Javascript 相关文章推荐
让人期待的2011年度最佳 jQuery 插件分享
Mar 16 Javascript
js 判断文件类型并控制表单提交示例代码
Nov 14 Javascript
JS测试显示屏分辨率以及屏幕尺寸的方法
Nov 22 Javascript
js利用事件的阻止冒泡实现点击空白模态框的隐藏
Jan 24 Javascript
D3.js中强制异步文件读取同步的几种方法
Feb 06 Javascript
微信小程序 检查接口状态实例详解
Jun 23 Javascript
Vue2.0 http请求以及loading展示实例
Mar 06 Javascript
Vue.js中的computed工作原理
Mar 22 Javascript
vue-cli项目配置多环境的详细操作过程
Oct 30 Javascript
vue移动端屏幕适配详解
Apr 30 Javascript
对layer弹出框中icon数字参数的说明介绍
Sep 04 Javascript
基于JavaScript伪随机正态分布代码实例
Nov 07 Javascript
VUE写一个简单的表格实例
Aug 06 #Javascript
VUE前后端学习tab写法实例
Aug 06 #Javascript
Vue路由前后端设计总结
Aug 06 #Javascript
vue实现行列转换的一种方法
Aug 06 #Javascript
微信小程序点餐系统开发常见问题汇总
Aug 06 #Javascript
详解使用WebPack搭建React开发环境
Aug 06 #Javascript
vue-cli3+typescript新建一个项目的思路分析
Aug 06 #Javascript
You might like
PHP制作百度词典查词采集器
2015/01/29 PHP
PHP中的魔术方法总结和使用实例
2015/05/11 PHP
浅谈mysql_query()函数的返回值问题
2016/09/05 PHP
PHP二维关联数组的遍历方式(实例讲解)
2017/10/18 PHP
PHP使用PDO抽象层获取查询结果的方法示例
2018/05/10 PHP
常用js脚本
2006/12/03 Javascript
围观tangram js库
2010/12/28 Javascript
Jquery选中或取消radio示例
2013/09/29 Javascript
JS简单计算器实例
2015/01/20 Javascript
JS基于cookie实现来宾统计记录访客信息的方法
2015/08/04 Javascript
jQuery过滤特殊字符及JS字符串转为数字
2016/05/26 Javascript
学习Angular中作用域需要注意的坑
2016/08/17 Javascript
Bootstrap缩略图的创建方法
2017/03/22 Javascript
用angular实现多选按钮的全选与反选实例代码
2017/05/23 Javascript
浅谈关于axios和session的一些事
2017/07/13 Javascript
基于node下的http小爬虫的示例代码
2018/01/11 Javascript
浅谈Vue初学之props的驼峰命名
2018/07/19 Javascript
js+canvas实现图片格式webp/png/jpeg在线转换
2020/08/22 Javascript
Vant 在vue-cli 4.x中按需加载操作
2020/11/05 Javascript
详解Python当中的字符串和编码
2015/04/25 Python
python在不同层级目录import模块的方法
2016/01/31 Python
解决python2.7用pip安装包时出现错误的问题
2017/01/23 Python
python入门教程之识别验证码
2017/03/04 Python
python 连接sqlite及简单操作
2017/06/30 Python
python使用turtle库与random库绘制雪花
2018/06/22 Python
使用python Fabric动态修改远程机器hosts的方法
2018/10/26 Python
matplotlib 画双轴子图无法显示x轴的解决方法
2020/07/27 Python
HTML5 CSS3实现一个精美VCD包装盒个性幻灯片案例
2014/06/16 HTML / CSS
澳大利亚牛仔裤商店:Just Jeans
2016/10/13 全球购物
英国打印机墨水和碳粉商店:Printerinks
2017/06/30 全球购物
DNA测试:Orig3n
2019/03/01 全球购物
盛大二次面试题
2016/11/18 面试题
JPA的特点
2014/10/25 面试题
房地产还款计划书
2014/01/10 职场文书
寒假生活随笔
2015/08/15 职场文书
Python基础之元编程知识总结
2021/05/23 Python