视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
Vue代码整洁之去重方法整理
2020-11-27 21:52:38 责编:小采
文档

准确来说,它并不算是代码。而是“硬编码”,从整体代码上来看,这是目前所有后台接口的域名

在开发过程中,一般来说至少是会有两个环境存在:开发环境、线上环境。而它们两的后台接口域名一般而言又不会重复,难道每次发布前都手动改一下域名么?

我们先来列举一下可能会出现的问题:

开发环境、线上环境域名不一致

团队协作中,开发者之间的开发域名不一致

当线上/开发 环境中的域名需要修改时

可以看到,当遇到上述问题时,项目中所有硬编码了域名的地方都是需要修改的,那么为什么要修改呢?

除了解决上面列举的具体问题之外,最根本的目的是:

保持唯一性

如果有两段/多段代码它们表示的含义完全一致,并且从目的上来说也是一致的。那么就应该尽可能将其只保留一处定义。

那么对于这个域名我们怎么处理呢?首先将其提炼出来:

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;

下载本文
显示全文
专题