您好,登錄后才能下訂單哦!
在開始本篇的主題之前,讓我們把上次遺留下來的問題都清理一下:
將其他組件中 axios
請求的地方封裝起來。
這里就不把代碼放在開頭了,相關(guān)代碼都放在文末,有興趣了解的童鞋可以先往下翻。
好了, 我們現(xiàn)在把上篇剩下的任務(wù)給完成了,接下來我們來正式開始本篇內(nèi)容吧。
去重是什么
字面上意思:去除重復(fù),在項目中,不可避免的會出現(xiàn)重復(fù)代碼。但是如果不好好去處理這些重復(fù)代碼,那很有可能就會給你很多“驚喜”。
如何為“重復(fù)” 下一個定義呢?
從最淺顯的層次來看, 相同即是重復(fù)。在我們上面的代碼中,每一個組件中都有這么一行代碼:
import RequestSender from '@/requestSender';
這就是重復(fù)代碼,在每一個需要發(fā)起請求的組件中你都會需要寫上這么一行代碼。那么讓我們就這個列舉一些可能出現(xiàn)的問題:
某一天修改了文件名
某一天移動了該文件
那么項目中需要修改的地方將會是多少呢?而在修改中會產(chǎn)生手誤的概率又會是多少呢?以上還是在單人開發(fā)的時候,如果團(tuán)隊協(xié)作開發(fā),這些情況的概率又會是什么樣的呢。
如何去重
當(dāng)然,對于上面這種引入型的代碼,類似移動文件,修改文件名這種操作。IDE 就能很好的幫你處理,比如 WebStorm
如果你使用重構(gòu)相關(guān)的功能去重命名,那么它會找出所有 “疑似”引用的代碼片段,你可以選擇所有相關(guān)的引用同時修改。
這是一種手段,很好的解決了上面這些問題。
那么讓我們來看看另一個重復(fù)代碼的問題:
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); } }
上面的代碼, 重點(diǎn)不在函數(shù)噢。 仔細(xì)看看它們有哪些地方重復(fù)了。
光從代碼上來看,其實有很多“重復(fù)”的地方,比如說 return
、static
、axios.get
、axios.post
。
這些重復(fù)有一部分是語法,有一部分是調(diào)用。這些都是不可避免的,因此這些重復(fù)代碼并不在我們需要重構(gòu)的范圍內(nèi)。那么,究竟是哪段代碼呢?
https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io
準(zhǔn)確來說,它并不算是代碼。而是“硬編碼”,從整體代碼上來看,這是目前所有后臺接口的域名
。
在開發(fā)過程中,一般來說至少是會有兩個環(huán)境存在:開發(fā)環(huán)境、線上環(huán)境。而它們兩的后臺接口域名一般而言又不會重復(fù),難道每次發(fā)布前都手動改一下域名么?
我們先來列舉一下可能會出現(xiàn)的問題:
開發(fā)環(huán)境、線上環(huán)境域名不一致
團(tuán)隊協(xié)作中,開發(fā)者之間的開發(fā)域名不一致
當(dāng)線上/開發(fā) 環(huán)境中的域名需要修改時
可以看到,當(dāng)遇到上述問題時,項目中所有硬編碼了域名
的地方都是需要修改的,那么為什么要修改呢?
除了解決上面列舉的具體問題之外,最根本的目的是:
保持唯一性
如果有兩段/多段代碼它們表示的含義完全一致,并且從目的上來說也是一致的。那么就應(yīng)該盡可能將其只保留一處定義。
那么對于這個域名我們怎么處理呢?首先將其提煉出來:
static Host = 'https://451ece6c-f618-436b-b4a2-517c6b2da400.mock.pstmn.io';
這樣,引用的地方就可以這么寫:
static GetBlogList() { return axios.get(`${Host}/list`); }
這樣,當(dāng)發(fā)現(xiàn)修改的時候,是不是只需要修改 Host
這么一個地方就好了呢?、
但是這樣還存在問題,如果要發(fā)布,或者是在 git
、 svn
上協(xié)作的時候呢? 每個人、每個環(huán)境都需要修改這個變量,并且還要在提交代碼時移除掉自己的修改以避免沖突。
可配置化
Host
的例子是非常常見的,當(dāng)我們需要發(fā)布、團(tuán)隊協(xié)作的時候,環(huán)境不同是非常常見的,有可能在自己電腦上 Host
是 localhost:8080
,換在另一個人電腦上就是 localhost:9099
了。那么線上環(huán)境有可能又是 xxx.xxx.com
、xx.xxx.com/api
諸如此類。
這里若羽實踐的解決方案是:
將與環(huán)境相關(guān)的硬編碼提煉成可配置項放入配置文件
配置文件模板化
配置模板文件多樣化
真正的配置文件是不會被提交上去,只有一個模板文件。由于配置文件并不會被提交,所以開發(fā)者之間的環(huán)境差異就可以忽略了,大家根據(jù)自己的環(huán)境修改配置文件即可。
那么對于線上環(huán)境、測試環(huán)境等等,建立對應(yīng)的配置文件模板即可。當(dāng)發(fā)布時,使用對應(yīng)環(huán)境的發(fā)布配置文件模板作為配置文件即可。
那么我們來實踐一下:
新建配置模板文件 config.js.template
:
const config = { HOST: '', }; export default config;
接下來復(fù)制粘貼模板文件,并重命名為 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;
好了,現(xiàn)在不管是在任何一個環(huán)境下,都可以游刃有余的切換域名了。而且這里面還有一個很有意思的事情:
所有的改動對于表現(xiàn)層而言是透明的。
簡單來說,我們在這里重構(gòu)了這么多的代碼,然而我們并不需要修改任何一個視圖組件中的代碼!??!
表面上還是原來的樣子,可實際上已經(jīng)“打掃”過了。這也是重構(gòu)中需要注意的一點(diǎn):
步子邁小一點(diǎn),邁準(zhǔn)一點(diǎn) 寫在后面
上篇中有人問到若羽說封裝請求的意義何在,axios
本身就是帶著 Promise
的支持了。
這里對這個問題做一個回應(yīng),立場僅代表若羽本人,并不為任何人“做代表”:
封裝并非為了 Promise
,而是為了將“發(fā)送請求”的這個動作封裝起來。因為這屬于數(shù)據(jù)獲取的行為,而后面 then
里的邏輯實際上是和業(yè)務(wù)掛鉤:為視圖設(shè)置數(shù)據(jù)。這是兩個不同的行為,就像后端一樣:ORM
它僅僅是負(fù)責(zé)從數(shù)據(jù)庫中取數(shù)據(jù)而已,真正對這個數(shù)據(jù)進(jìn)行邏輯操作的,并不是它。這也是接下來博文的主題:專一,一個函數(shù)應(yīng)當(dāng)只負(fù)責(zé)一件事情。
這一篇文章便表示了另一層意思:去重,在第一層封裝的過程中我們發(fā)現(xiàn)了域名
的硬編碼問題(不封裝也是一樣),因此在這里如果不做封裝的話,即使將域名提煉出來,涉及到修改的文件同樣也會較多。不過這種修改是一次性的。
以上便是若羽對上一篇中示例的解釋。
歡迎大家發(fā)表評論,共同探討。
上篇重構(gòu)代碼
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('發(fā)布成功'); } }) } } } </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;
以上就是關(guān)于Vue代碼整潔之去重的相關(guān)知識點(diǎn),感謝大家的閱讀和對億速云的支持。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。