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 相关文章推荐
jquery 事件执行检测代码
Dec 09 Javascript
jQuery中ajax的使用与缓存问题的解决方法
Dec 19 Javascript
ExtJS如何设置与获取radio控件的选取状态
Jan 22 Javascript
js中自定义方法实现停留几秒sleep
Jul 11 Javascript
在easyUI开发中,出现jquery.easyui.min.js函数库问题的解决办法
Sep 11 Javascript
javascript中的3种继承实现方法
Jan 27 Javascript
JS中的hasOwnProperty()、propertyIsEnumerable()和isPrototypeOf()
Aug 11 Javascript
Vue.js系列之项目搭建(1)
Jan 03 Javascript
vue组件间通信子与父详解(二)
Nov 07 Javascript
vsCode安装使用教程和插件安装方法
Aug 24 Javascript
Vue实现返回顶部按钮实例代码
Oct 21 Javascript
ant design vue中表格指定格式渲染方式
Oct 28 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中GET变量的使用
2006/10/09 PHP
php sybase_fetch_array使用方法
2014/04/15 PHP
PHP中的多行字符串传递给JavaScript的两种方法
2014/06/19 PHP
PHP反射机制用法实例
2014/08/28 PHP
thinkPHP中验证码的简单使用方法
2015/12/26 PHP
php版微信公众平台入门教程之开发者认证的方法
2016/09/26 PHP
ExtJS的拖拽效果示例
2013/12/09 Javascript
用js+iframe形成页面的一种遮罩效果的具体实现
2013/12/31 Javascript
JScript中的条件注释详解
2015/04/24 Javascript
javascript实现确定和取消提示框效果
2015/07/10 Javascript
JS实现光滑展开合拢的菜单效果代码
2015/09/16 Javascript
跟我学习javascript的严格模式
2015/11/16 Javascript
JavaScript事件类型中焦点、鼠标和滚轮事件详解
2016/01/25 Javascript
JavaScript浏览器对象之一Window对象详解
2016/06/03 Javascript
jQuery实现背景滑动菜单
2016/12/02 Javascript
使用BootStrap建立响应式网页——通栏轮播图(carousel)
2016/12/21 Javascript
高性能的javascript之加载顺序与执行原理篇
2018/01/14 Javascript
vue-cli 3.0 版本与3.0以下版本在搭建项目时的区别详解
2018/12/11 Javascript
Vue.js组件props数据验证实现详解
2019/10/19 Javascript
动态实现element ui的el-table某列数据不同样式的示例
2021/01/22 Javascript
Python深入学习之内存管理
2014/08/31 Python
python科学计算之numpy——ufunc函数用法
2019/11/25 Python
使用pth文件添加Python环境变量方式
2020/05/26 Python
Django正则URL匹配实现流程解析
2020/11/13 Python
基于canvas的骨骼动画的示例代码
2018/06/12 HTML / CSS
美国玩具公司:U.S.Toy
2018/05/19 全球购物
伦敦的高级牛仔布专家:Trilogy
2018/08/06 全球购物
颇特女士香港官网:NET-A-PORTER香港
2021/03/08 全球购物
数据库什么时候应该被重组
2012/11/02 面试题
电子专业推荐信范文
2013/11/18 职场文书
自我评价范文点评
2013/12/04 职场文书
2014年党课学习材料
2014/05/11 职场文书
党员干部作风建设思想汇报范文
2014/10/25 职场文书
2016领导干部廉洁自律心得体会
2016/01/13 职场文书
导游词之无锡华莱坞
2019/12/02 职场文书
MySQL中order by的使用详情
2021/11/17 MySQL