自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

記一次Vue項(xiàng)目的重構(gòu)

開發(fā) 開發(fā)工具
頁面view相關(guān)的數(shù)據(jù)才使用Vuex來管理,頁面功能性ajax(例如簽到、兌換)不要使用vuex;「首次后端渲染」和「非首次跳轉(zhuǎn)」的view數(shù)據(jù)都通過commit mutation來修改state,最終映射到DOM表現(xiàn)上;功能性ajax則在組件內(nèi)自己發(fā)請求實(shí)現(xiàn),保持組件內(nèi)聚。

[[196161]]

上周沒有更新原創(chuàng)技術(shù)文章,原因是忙著重構(gòu)一個(gè)新接手的項(xiàng)目,此項(xiàng)目因?yàn)轫?xiàng)目技術(shù)負(fù)責(zé)人離職,雖然投入人力持續(xù)增多,前端達(dá)到4人,后端3人,但因?yàn)樾聟⑴c的童鞋對代碼結(jié)構(gòu)和業(yè)務(wù)的理解,導(dǎo)致項(xiàng)目開發(fā)了一個(gè)多月,還有一堆問題,達(dá)不到上線要求。接手項(xiàng)目之后,一開始對項(xiàng)目業(yè)務(wù)場景和代碼進(jìn)行簡單的了梳理,跟了一天項(xiàng)目,觀察提測后FE+RD的狀態(tài),自己也動(dòng)手改了一天代碼,不管是FE+RD包括自己都覺得實(shí)在是太難受了,小坑大坑不斷,于是決定重構(gòu)。重構(gòu)不是個(gè)人沖動(dòng),而是的的確確存在各種大大小小的問題:

1.接口太碎:項(xiàng)目本身按照Vue組件化開發(fā),但是頁面每個(gè)組件獨(dú)自采用vuex+ajax請求管理自己的數(shù)據(jù),比如:首頁由輪播圖、各種列表和用戶信息展現(xiàn)組成,導(dǎo)致首頁從上到下7~8個(gè)模塊,每個(gè)模塊都各自發(fā)自己的請求,訪問首頁需要同時(shí)發(fā)出8個(gè)ajax請求

2.因?yàn)椤?」提到的,單個(gè)組件數(shù)據(jù)都是使用Vuex進(jìn)行管理,導(dǎo)致Vuex的store太亂:而且FE按照組件去開發(fā),各自跟后端RD兌接口、聯(lián)調(diào),但是沒有人來統(tǒng)籌安排,導(dǎo)致大量重復(fù)工作;除此之外,action和mutation中的業(yè)務(wù)邏輯代碼太多,而不同頁面需要不同的數(shù)據(jù)格式,則導(dǎo)致:

a.或者在mutation當(dāng)中對數(shù)據(jù)進(jìn)行重新整理

b.或者新開個(gè)接口,這樣就造成接口越來越多,mutation部分代碼越來越重。

3.一開始設(shè)計(jì)或者溝通有誤。比如:用戶信息相關(guān)的接口,需要傳入用戶id(uid),而不是通過登錄cookie從passport獲取;第三方接口需要用戶信息,竟然請求的時(shí)候?qū)ookie發(fā)給對方(幸好cookie是http only的,沒有調(diào)通被我及時(shí)發(fā)現(xiàn))

4.重復(fù)代碼太多,抽象能力太差。一份代碼在多個(gè)地方復(fù)制,導(dǎo)致代碼改來改去最后都不知道哪里改了哪里沒改

5.命名太亂,包括url、方法名之類,還有錯(cuò)別字,getAdcontent(用戶地址信息),getmaildetail(用戶地址信息)

6.研發(fā)人員缺乏全局意識(shí),只管自己的代碼,而不關(guān)心整個(gè)流程。由于前后投入人較多,沒人對整個(gè)項(xiàng)目有把控,只能面向自己的需求編程。比如:積分獲取頁面,獲取成功之后,聯(lián)調(diào)成功,但是實(shí)際在積分獲取列表頁面卻沒有相關(guān)的記錄信息;在比如:任何用戶都可以領(lǐng)走別人的獎(jiǎng)品,原因后端沒做獎(jiǎng)品是否是當(dāng)前登錄用戶獲取的校驗(yàn)

7.問題定位能力不夠,遇見問題一調(diào)就是半天,找不到根本問題

介紹下項(xiàng)目背景:

此項(xiàng)目是一個(gè)用戶積分任務(wù)和消費(fèi)項(xiàng)目,一些頁面需要用戶登錄,頁面主要包括:首頁、任務(wù)+列表、商品+列表、個(gè)人信息和記錄以及其他類(說明和規(guī)則等)

項(xiàng)目用Vue+yog2編寫,ajax請求部分使用vue resource

架構(gòu)改造

整個(gè)項(xiàng)目還是用Vue+yog2來寫,針對進(jìn)入頁面分為兩種情況:

  1. 第一次通過網(wǎng)站URL進(jìn)入某個(gè)頁面,我稱為:「首次后端渲染」
  2. 非首次已經(jīng)進(jìn)入頁面URL后,用戶點(diǎn)擊鏈接在項(xiàng)目內(nèi)跳頁,我稱之為:「非首次跳轉(zhuǎn)」

整個(gè)流程整理如下:兩個(gè)流程從「兩個(gè)小人」開始看起

后端node Server代碼部分

代碼流程如下:

  1. router → middleware → page/api action → model → ral請求數(shù)據(jù) 

其中在action部分,專門寫了個(gè) baseAction函數(shù),封裝了重復(fù)的代碼,使用時(shí)傳入用于獲取數(shù)據(jù)的model方法和處理數(shù)據(jù)的方法即可。

render部分,針對頁面第一次請求需要將頁面數(shù)據(jù)放在HTML片段中chunk輸出,而不是通過ajax請求(為什么不用vue ssr,可以看下歷史公眾號(hào)文章《Vue SSR 從入門到Case Study》,之后單頁內(nèi)跳轉(zhuǎn)是ajax請求)。詳細(xì)代碼如下:

client.tpl 部分代碼:

 

baseAction 部分實(shí)現(xiàn)chunked

Client Vue部分代碼

client主要流程是:

  1. vue router → created時(shí)期 判斷是否有頁面數(shù)據(jù) → 
  2. 提交mutation(有數(shù)據(jù)),dispatch action(異步拉取數(shù)據(jù))→ state觸發(fā)修改,頁面dom生成 

這部分流程圖主要展現(xiàn)是Vuex和Vue resource部分的代碼,通過Vuex的dispatch action,觸發(fā)Vue resource的異步請求,等返回?cái)?shù)據(jù)則commit mutation。

后端渲染+SPA單頁應(yīng)用

經(jīng)過改造后整個(gè)流程變成:

1.「首次后端渲染」:此時(shí)需要后端渲染主要HTML+頁面數(shù)據(jù),利用chunked,先將不依賴后端數(shù)據(jù)部分返給瀏覽器,頁面數(shù)據(jù)和后面的HTML拿到數(shù)據(jù)后再返給瀏覽器。 client.tpl被「一分為二」:HTML[0] + HTML[1]

a.將頁面通用的css和js lib庫,放在HTML[0]中,首先返回,瀏覽器先解析下載

b.業(yè)務(wù)代碼初始化代碼放在HTML[1], 等到獲取到后臺(tái)API數(shù)據(jù)一起返回

2.「非首次跳轉(zhuǎn)」:這是一個(gè)單頁應(yīng)用的流程,用戶點(diǎn)擊鏈接,實(shí)際走的是vue的router,然后出發(fā)vue頁面渲染,URL是通過history pushState mode更改實(shí)際URL,這時(shí)候如果強(qiáng)刷或者復(fù)制url在瀏覽器打開,又走「首次后端渲染」

a.vue頁面渲染需要的數(shù)據(jù)是通過vue-resource發(fā)起ajax請求,拿到數(shù)據(jù)之后commit mutation改變state

Vuex梳理

之前代碼每個(gè)組件都單獨(dú)ajax請求自己的數(shù)據(jù),導(dǎo)致Vuex的module特別多特別亂,而且后端api接口太多太碎,不好維護(hù)。最后開發(fā)的童鞋自己都在群里抱怨,找個(gè)action或者mutation都不知道在哪個(gè)文件內(nèi),需要搜代碼。。

首先做約定,明確什么時(shí)候使用Vuex:

頁面view相關(guān)的數(shù)據(jù)才使用Vuex來管理,頁面功能性ajax(例如簽到、兌換)不要使用vuex;「首次后端渲染」和「非首次跳轉(zhuǎn)」的view數(shù)據(jù)都通過commit mutation來修改state,最終映射到DOM表現(xiàn)上;功能性ajax則在組件內(nèi)自己發(fā)請求實(shí)現(xiàn),保持組件內(nèi)聚;

P.S:這就是「貧血組件」和「充血組件」的區(qū)別,本身組件內(nèi)的狀態(tài)和邏輯都放在全局store管理,會(huì)增加store復(fù)雜度,降低效率(代碼性能和開發(fā)效率)

然后,收斂vuex module

收斂是根據(jù)業(yè)務(wù)頁面做的,前文提到:

頁面主要包括:首頁、任務(wù)+列表、商品+列表、個(gè)人信息和記錄以及其他類(說明和規(guī)則等)

其中需要數(shù)據(jù)的有:首頁、任務(wù)(詳情、列表)、商品(詳情、列表)和個(gè)人中心四個(gè)。

改造前module:

改造后module針對業(yè)務(wù)梳理的四個(gè)大頁面內(nèi)容,保留了四個(gè):

減少mutation數(shù)據(jù)處理邏輯

復(fù)用后端接口數(shù)據(jù)格式,減少mutation數(shù)據(jù)處理邏輯

改造前很多action存在下面的代碼(注意箭頭部分):

其中這個(gè)循環(huán)主要做兩件事情:修改 type、修改 img_url為 url,實(shí)際根本沒有必要:

  • 修改 type:實(shí)際這已經(jīng)是頁面view層的邏輯了,在vue的模板或者computed中做更合適
  • 修改 img_url為 url:這里實(shí)際是產(chǎn)品的封面圖,改成 url反而更不合適了,而且導(dǎo)致了數(shù)據(jù)不一致

代碼可以直接用 item即可!即不需要做額外的循環(huán)處理,保證數(shù)據(jù)一致性,避免前端的二次設(shè)計(jì)

API顯性聲明

之前所有的api都是走了一個(gè) proxy,通過node轉(zhuǎn)發(fā)一下,直接到了后臺(tái)API接口,代碼如下:

看似很方便甚至有點(diǎn)暗爽的實(shí)現(xiàn),實(shí)則帶來了下面的問題:

  1. 接口非顯性聲明,降低可控性,造成沒法枚舉有多少接口,各個(gè)接口需要什么參數(shù),增加維護(hù)成本
  2. 安全性!后臺(tái)這個(gè)服務(wù)是完全暴漏給了前端,如果存在敏感的接口,前端js就可以直接透傳利用

改造后的代碼放在model層,供「首次后端渲染」和「非首次單頁」ajax請求使用:

優(yōu)化

除了做代碼重構(gòu)改造外,還在間隙中做了一些優(yōu)化,這里記錄一下:

后端渲染使用chunked

詳見本文「后端node server部分代碼」和「后端渲染+SPA」

數(shù)據(jù)復(fù)用

很多頁面設(shè)計(jì)會(huì)在首頁和列表頁面存在有產(chǎn)品的title、圖片和簡單的一些meta,例如下圖:

[[196162]]

點(diǎn)擊鏈接進(jìn)去詳情頁面可以直接利用,這部分?jǐn)?shù)據(jù)我們做了復(fù)用。

實(shí)現(xiàn)方法是:頁面點(diǎn)擊的時(shí)候,將該條數(shù)據(jù)內(nèi)容commit給下一個(gè)頁面的mutation。

緩存

緩存在node和前端Ajax API多有,后端node主要緩存的是首頁,因?yàn)槭醉撔枰埱?個(gè)接口(接口梳理后),其中三個(gè)接口是跟用戶登錄態(tài)無關(guān)的,這三個(gè)接口可以用lru-cache緩存起來。

前端的ajax api緩存是在 get請求增加的,可以根據(jù)實(shí)際情況用,根據(jù)url作為key,使用sessionStorage存儲(chǔ)(同時(shí)cache類自己實(shí)現(xiàn)了緩存時(shí)間)

技巧

除了優(yōu)化外,我在介紹下兩個(gè)技巧:單頁切換view的loading和統(tǒng)一的錯(cuò)誤處理。

在單頁跳轉(zhuǎn)內(nèi),下一個(gè)view需要API請求獲取數(shù)據(jù),然后才能渲染,這時(shí)候需要加載個(gè)loading顯示(或者做個(gè)切換動(dòng)效)。

原理是:

1.利用eventBus,在router中添加兩個(gè)事件 closeLoading和 vue.action.error,分別用于「關(guān)閉loading」和「展現(xiàn)頁面數(shù)據(jù)錯(cuò)誤的錯(cuò)誤頁」

l2.oading展現(xiàn)在router的 beforeEach的鉤子內(nèi)實(shí)現(xiàn),loading的事件在vuex的action獲取數(shù)據(jù)成功之后發(fā)送

3.錯(cuò)誤的觸發(fā)有vuex 的 action / mutation 來發(fā)送事件

eventBus也不用自己寫,可以直接用Vue實(shí)例的 $on、 $emit、 $once等就夠了,代碼如下:

  1. import Vue from 'vue' 
  2. export default new Vue() 

總結(jié)

重構(gòu)主要做的事情是:

1.統(tǒng)一接口請求,重新梳理API;

2.收斂Vuex store設(shè)計(jì)(包括mutation/action的聚合,state簡化);明確Vuex的使用邊界

3.明確組件職責(zé)邊界,劃分「充血組件」與「貧血組件」

4.抽象封裝重復(fù)的代碼邏輯

5.做了一些簡單優(yōu)化

說下成果:項(xiàng)目已經(jīng)delay很久,從4月初到5月初已經(jīng)一個(gè)月了還沒上線,接手項(xiàng)目是五一前,整個(gè)重構(gòu)共2個(gè)人力用了三天完成95%的工作,目前已經(jīng)提測,

下面是重構(gòu)項(xiàng)目的團(tuán)隊(duì)內(nèi)部問題總結(jié):

1.項(xiàng)目開發(fā)中一定要有大局意識(shí),雖然現(xiàn)在項(xiàng)目多是分組件來的開發(fā)方式,但是開發(fā)前要跟大家交代清楚約定、規(guī)范,什么該做什么不該做;

2.技術(shù)負(fù)責(zé)人多 check 代碼,防止錯(cuò)誤的道路上越行越遠(yuǎn);

3.要有全局意識(shí),關(guān)注整個(gè)流程,不要只看到自己的「一畝三分地」,比如:在某個(gè)商品頁面,購買/兌換成功了,不要認(rèn)為沒有問題了,可能記錄頁面還沒有展現(xiàn)(后臺(tái)接口沒有入庫);

4.Don’t repeat yourself!看見重復(fù)代碼就渾身難受,「抽象」能力是工程師的基本能力。

5.增強(qiáng)debug能力,發(fā)現(xiàn)問題直覺就能判斷出來哪個(gè)環(huán)境,然后針對性debug

【本文為51CTO專欄作者“三水清”的原創(chuàng)稿件,轉(zhuǎn)載請通過微信公眾號(hào)聯(lián)系作者獲取授權(quán)】

戳這里,看該作者更多好文

責(zé)任編輯:武曉燕 來源: 51CTO專欄
相關(guān)推薦

2021-11-11 16:14:04

Kubernetes

2022-01-07 11:48:59

RabbitMQGolang 項(xiàng)目

2014-08-11 09:31:52

2023-04-06 07:53:56

Redis連接問題K8s

2013-04-01 10:27:37

程序員失業(yè)

2011-02-22 09:29:23

jQueryJavaScript

2017-12-19 14:00:16

數(shù)據(jù)庫MySQL死鎖排查

2019-03-15 16:20:45

MySQL死鎖排查命令

2023-06-07 07:31:04

PC端app脫殼技巧

2019-08-26 09:50:09

2021-12-20 10:15:16

zip密碼命令網(wǎng)絡(luò)安全

2023-10-10 12:05:45

2013-01-17 10:31:13

JavaScriptWeb開發(fā)firebug

2018-07-11 10:24:33

數(shù)據(jù)恢復(fù)數(shù)據(jù)刪除

2021-05-13 08:51:20

GC問題排查

2021-01-08 13:52:15

Consul微服務(wù)服務(wù)注冊中心

2022-02-28 08:23:02

開源項(xiàng)目重構(gòu)

2018-02-23 13:41:05

數(shù)據(jù)庫MySQL數(shù)據(jù)恢復(fù)

2022-11-29 21:26:26

跨域配置

2023-01-04 18:32:31

線上服務(wù)代碼
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)