關(guān)于后臺(tái)管理系統(tǒng)前端項(xiàng)目的思考

開(kāi)發(fā)后臺(tái)管理系統(tǒng)是大部分前端開(kāi)發(fā)人員接觸過(guò)的項(xiàng)目碟狞,如何更好的進(jìn)行項(xiàng)目的搭建律罢、組件的開(kāi)發(fā)、數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)等等桶唐,這些都是需要考慮的問(wèn)題栅葡。以下是我結(jié)合一些項(xiàng)目的經(jīng)歷和其他大佬的項(xiàng)目代碼與技術(shù)分享,做出了對(duì)于后臺(tái)管理系統(tǒng)中前端項(xiàng)目的思考

1. 了解需求莽红,熟悉掌握需求

這一要求無(wú)論是對(duì)于前端開(kāi)發(fā)人員或是其他端的開(kāi)發(fā)人員妥畏,都是能夠順利開(kāi)發(fā)項(xiàng)目的前提邦邦。在開(kāi)發(fā)項(xiàng)目之前,需對(duì) PM 的需求了然于胸醉蚁,對(duì)原型設(shè)計(jì)能夠充分掌握燃辖。理解每一個(gè)操作邏輯的含義,并且擴(kuò)散思維思考如何進(jìn)行組件和數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)网棍。但是單獨(dú)只是對(duì)需求文檔和原型進(jìn)行閱讀是比較容易遺漏某些功能點(diǎn)的黔龟,最好能夠?qū)?xiàng)目重新設(shè)計(jì)一張 思維導(dǎo)圖 ,從開(kāi)發(fā)自己的角度進(jìn)行設(shè)計(jì)滥玷,從項(xiàng)目整體的根節(jié)點(diǎn)出發(fā)氏身,細(xì)分每一個(gè)模塊,每個(gè)模塊下設(shè)計(jì)好對(duì)應(yīng)的需求惑畴,確保每一個(gè)功能不被遺漏蛋欣。雖然多花了設(shè)計(jì)思維導(dǎo)圖的時(shí)間,但我覺(jué)得這是值得的如贷,這樣不僅僅能夠增加對(duì)于整體項(xiàng)目的理解陷虎,也能更好的及時(shí)發(fā)現(xiàn)項(xiàng)目的難點(diǎn)和疑惑點(diǎn)。

image.png
image.png

2. 確定技術(shù)選型

后臺(tái)管理系統(tǒng)的主流技術(shù)選型為 Vue+ElemetUI杠袱,不過(guò)個(gè)人覺(jué)得在組件設(shè)計(jì)上 Ant Design VueUI 框架設(shè)計(jì)得好一些尚猿,更多的是采取數(shù)據(jù)驅(qū)動(dòng)組件的設(shè)計(jì)模式,在項(xiàng)目開(kāi)發(fā)中可以更方便的解耦邏輯函數(shù)楣富。不過(guò) UI 框架的選擇還是得結(jié)合開(kāi)發(fā)人員團(tuán)隊(duì)自身對(duì)于某一個(gè)的熟練程度和是否有對(duì)應(yīng)的 UI 框架能更好的解決項(xiàng)目中存在的難點(diǎn)進(jìn)行綜合比較凿掂。
全局按需引入 element-ui 組件:

import Vue from "vue";
···
import { Input } from "element-ui";
Vue.use(Input);

組件使用:

<el-input
  v-model="user"
  clearable
  @keyup.enter.native="search"
  @clear="search"
></el-input>

3. 設(shè)計(jì)項(xiàng)目結(jié)構(gòu)

通過(guò) Vue 腳手架工具搭建的前端項(xiàng)目在 src 文件夾下可分為以下幾部分:

  1. 路由層 router
  2. 靜態(tài)文件層 assets
  3. 頁(yè)面結(jié)構(gòu)層 views
  4. 組件結(jié)構(gòu)層 components
  5. 全局狀態(tài)管理層 store
  6. 功能邏輯處理層 util
  7. 常量管理層 constants

Vue 項(xiàng)目中還可以引入更多的配置如混入層 mixins 、過(guò)濾層 filtters 等纹蝴。
在項(xiàng)目開(kāi)發(fā)中庄萎,需要區(qū)分開(kāi)業(yè)務(wù)功能和非業(yè)務(wù)功能的邏輯設(shè)計(jì),對(duì)于一些可以解耦出來(lái)的非業(yè)務(wù)功能函數(shù)骗灶,一般不直接在開(kāi)發(fā)頁(yè)面的業(yè)務(wù)邏輯中直接定義此函數(shù)惨恭,而是需要抽離出來(lái),可供多個(gè)業(yè)務(wù)功能函數(shù)進(jìn)行調(diào)用耙旦。
組件結(jié)構(gòu)層 components 中一般也只開(kāi)發(fā)非業(yè)務(wù)功能相關(guān)的頁(yè)面組件或功能組件脱羡,以供多個(gè)頁(yè)面結(jié)構(gòu)進(jìn)行調(diào)用,若一個(gè)頁(yè)面需分成幾個(gè)組件開(kāi)發(fā)免都,且此子組件屬于業(yè)務(wù)功能的锉罐,建議直接在頁(yè)面結(jié)構(gòu)層 views 中定義,開(kāi)發(fā)和維護(hù)同一個(gè)頁(yè)面也比較方便绕娘。
src 文件夾下結(jié)構(gòu)如下:

├─assets
├─components
├─constants
├─mixins
├─request
├─router
├─store
├─utils
└─views

4. 數(shù)據(jù)請(qǐng)求 methods中 OR actions中

一般項(xiàng)目中對(duì)于數(shù)據(jù)請(qǐng)求的方式都是基于 methods 鉤子或其他生命周期鉤子中調(diào)用請(qǐng)求方法脓规,也存在一些項(xiàng)目中是通過(guò)發(fā)送一個(gè) disptach 異步請(qǐng)求方法在 actions 中調(diào)用請(qǐng)求函數(shù)。使用后者的說(shuō)法是便于統(tǒng)一管理請(qǐng)求接口险领,并對(duì)請(qǐng)求返回的數(shù)據(jù)進(jìn)行統(tǒng)一的管理侨舆。
綜合以上兩種做法秒紧,可以優(yōu)化項(xiàng)目中的請(qǐng)求方式,若請(qǐng)求接口發(fā)出后返回的數(shù)據(jù)需要在多個(gè)頁(yè)面或多個(gè)不同的組件中共享和使用挨下,則推薦在需要發(fā)請(qǐng)求的函數(shù)中 dispath 觸發(fā)熔恢,在 actions 中發(fā)送請(qǐng)求,返回的數(shù)據(jù)保存在全局狀態(tài)管理 state 中臭笆。
methods 中發(fā)送請(qǐng)求方式:

getGraphicCode () {
  let vm = this;
  api.login.getCheckCode({
    type: '2'
  }).then(res => {
    if (res.code === '000') {
      vm.graphicCode = 'data:image/png;base64,' + res.data.img;
      vm.imgId = res.data.imgId;
    } else {
      vm.$message.error(res.msg);
    }
  })
}

actions 中發(fā)送請(qǐng)求方式:

findAllRoles({ commit }) {
  return new Promise((resolve, reject) => {
    api.systemAccount.findAllRoles().then(response => {
      if (response.code === "000" && response.success) {
        commit(MUTATIONS_TYPE.AllROLES, response.data)
        resolve(response);
      } else {
        reject(new Error(response.code, response.msg))
      }
    })
  })
},

5. 登錄與權(quán)限管理

token 驗(yàn)證是目前大部分前后端分離的 Web 項(xiàng)目做登錄驗(yàn)證比較常見(jiàn)的方法叙淌。前端通過(guò)發(fā)送賬號(hào)和密碼或賬號(hào)和驗(yàn)證碼給到后端后,后端驗(yàn)證通過(guò)會(huì)返回一個(gè)唯一的 token 作為該用戶的登錄憑證愁铺,在之后的每個(gè)請(qǐng)求當(dāng)中鹰霍,請(qǐng)求頭中都需帶上這個(gè) token 作為后端的登錄校驗(yàn)。 token 有過(guò)期的機(jī)制茵乱,可以在請(qǐng)求攔截中做邏輯判斷處理茂洒,若當(dāng)前時(shí)間接近了過(guò)期時(shí)間,則通過(guò)更新 token 的接口請(qǐng)求更新 token 似将,在之后的請(qǐng)求中帶上新的 token 获黔。以此循環(huán),若用戶過(guò)長(zhǎng)時(shí)間無(wú)操作在验,則可認(rèn)為用戶為離線狀態(tài),在用戶之后的第一次請(qǐng)求時(shí)堵未,由于 token 已經(jīng)過(guò)期腋舌,訪問(wèn)后端接口會(huì)發(fā)生錯(cuò)誤,根據(jù)后端返回的錯(cuò)誤狀態(tài)碼作為判斷渗蟹,將系統(tǒng)定向至登錄頁(yè)面块饺。
通過(guò)帶有 token 請(qǐng)求頭的請(qǐng)求方法,后端可以判斷到是哪一個(gè)用戶雌芽,前端也可以通過(guò)獲取權(quán)限接口獲得該用戶的權(quán)限列表授艰,根據(jù)權(quán)限列表做一份路由映射表,如果后端返回的數(shù)據(jù)結(jié)構(gòu)與前端的路由設(shè)置的數(shù)據(jù)結(jié)構(gòu)不同世落,此時(shí)還需編寫(xiě)此映射路由的業(yè)務(wù)功能函數(shù)淮腾。如果該用戶擁有此路由權(quán)限,則通過(guò)在全局路由監(jiān)控中 router.beforeEach 進(jìn)行 router 中的 addRoutes 方法將有權(quán)限的路由配置添加到路由當(dāng)中屉佳,側(cè)邊欄也可根據(jù)路由列表中的 meta 字段中關(guān)鍵字的判斷進(jìn)行相應(yīng)的渲染谷朝。如果權(quán)限的顆粒度小到一個(gè)按鈕,則可根據(jù)后端返回的權(quán)限列表映射出的權(quán)限參數(shù)武花,通過(guò) v-if 進(jìn)行判斷該功能組件是否渲染仿野。
在路由管理中通過(guò) router.beforeEach 鉤子中判斷當(dāng)前的路由權(quán)限是否為空邑遏,是的話則可執(zhí)行獲取權(quán)限路由的接口:

store.dispatch("getUserInfoAndAuthorityInfo").then(res => {
  // 根據(jù)后端返回的路由權(quán)限格式轉(zhuǎn)成前端路由配置格式
  const rolesRoute = setAsyncRouterMap(res.menuList, asyncRouterMap, mainChildrenAsyncRoutes)
  store.commit(Vue.VUEX_TYPES.ROLESROUTE, rolesRoute);
  // 添加路由
  router.addRoutes(rolesRoute);
  next({ ...to })
}).catch(() => {
  Message.error("驗(yàn)證失敗")
  next('/login')
})

6. 常量枚舉值管理

在項(xiàng)目當(dāng)中對(duì)關(guān)鍵的常量枚舉值進(jìn)行管理是非常有必要的。比如在項(xiàng)目當(dāng)中后端用某個(gè)狀態(tài)碼 1 代表賬號(hào)為啟用狀態(tài)材彪,如果在項(xiàng)目當(dāng)中多次使用 ===1 去判斷賬號(hào)是否為啟用狀態(tài),當(dāng)需要更改這個(gè)狀態(tài)碼的時(shí)候蚣录,對(duì)于前端來(lái)說(shuō)是一件十分麻煩的事情,所以可以通過(guò)把 1 賦值給一個(gè)常量,在項(xiàng)目代碼中引用這個(gè)常量站叼,如果需要更改狀態(tài)碼的時(shí)候,則直接改變這個(gè)賦值給常量枚舉值的狀態(tài)碼即可回怜,常量的配置也可提醒開(kāi)發(fā)人員此參數(shù)不可輕易修改大年,便于項(xiàng)目的維護(hù)和統(tǒng)一管理。一般常量枚舉值的管理寫(xiě)在 constants 層中玉雾,常量的變量名使用大寫(xiě)字母編寫(xiě)翔试。
狀態(tài)枚舉值得配置如下:

/**
 * 賬號(hào)狀態(tài)對(duì)照表
 * "0" 未啟用 NOTUSED_CODE
 * "1" 已啟用 ENABLE_CODE
 * "2" 已停用 DISABLE_CODE
 */

const NOTUSED_CODE = "0";
const ENABLE_CODE = "1";
const DISABLE_CODE = "2";

const ACCOUNT_TYPE = {
  [NOTUSED_CODE]: "未啟用",
  [ENABLE_CODE]: "已啟用",
  [DISABLE_CODE]: "已停用"
};

export default Object.freeze({
  NOTUSED_CODE,
  ENABLE_CODE,
  DISABLE_CODE,
  ACCOUNT_TYPE
});

7. 組件設(shè)計(jì)

前端項(xiàng)目當(dāng)中可以把展示組件分為兩部分,分別為頁(yè)面組件和功能組件复旬。對(duì)于頁(yè)面組件垦缅,常用于展現(xiàn)頁(yè)面的整體內(nèi)容,承擔(dān)著業(yè)務(wù)邏輯的正常運(yùn)行驹碍,與業(yè)務(wù)比較有強(qiáng)的耦合性壁涎。功能組件是用于展現(xiàn)和處理某一單一或某一模塊的功能,功能組件并不關(guān)心頁(yè)面的業(yè)務(wù)邏輯志秃,充當(dāng)著一個(gè)函數(shù)的作用怔球,只要有輸入便有對(duì)應(yīng)的輸出,并可在多個(gè)頁(yè)面組件或功能組件中被調(diào)用浮还。綜上竟坛,在設(shè)計(jì)頁(yè)面組件的時(shí)候,不僅應(yīng)該考慮該組件能夠正常的完成業(yè)務(wù)的功能钧舌,還要考慮其是否能夠脫離業(yè)務(wù)成為一個(gè)功能組件担汤,對(duì)于內(nèi)容比較多的頁(yè)面組件,可以在其同級(jí)目錄下新建多個(gè)子頁(yè)面組件共同構(gòu)建洼冻。在設(shè)計(jì)功能組件時(shí)崭歧,需考慮組件的布局、邏輯撞牢、視圖率碾,功能組件的設(shè)計(jì)難度在于其要考慮到滿足不斷更新的需求變化,可擴(kuò)展性普泡,靈活性是設(shè)計(jì)的一大挑戰(zhàn)播掷。
頁(yè)面組件目錄格式如下:


image.png
image.png

8. 必要的開(kāi)發(fā)文檔或注釋

項(xiàng)目的開(kāi)發(fā)文檔可編寫(xiě)為md文件格式存放于項(xiàng)目的根目錄,一份好的開(kāi)發(fā)文檔能夠?qū)?xiàng)目的背景進(jìn)行介紹撼班,說(shuō)明項(xiàng)目的結(jié)構(gòu)和開(kāi)發(fā)的步驟歧匈,更有利于其他開(kāi)發(fā)人員參與或接手項(xiàng)目。對(duì)于項(xiàng)目當(dāng)中使用到的與業(yè)務(wù)功能耦合的邏輯函數(shù)砰嘁,較為復(fù)雜的件炉,編寫(xiě)函數(shù)的介紹以及使用方法勘究,做好邊界條件判斷,示范輸入數(shù)據(jù)以及對(duì)應(yīng)的輸出結(jié)果斟冕,可在項(xiàng)目中新建 docs 文件夾存放開(kāi)發(fā)過(guò)程中的使用文檔口糕。對(duì)于非復(fù)雜功能的業(yè)務(wù)邏輯函數(shù)或非業(yè)務(wù)邏輯函數(shù),可直接在定義函數(shù)之前編寫(xiě)注釋磕蛇,說(shuō)明函數(shù)作用功能景描,以及對(duì)應(yīng)的輸入和輸入?yún)?shù)的類型。

每次的開(kāi)發(fā)過(guò)程都可當(dāng)做是一個(gè)學(xué)習(xí)和總結(jié)經(jīng)驗(yàn)的過(guò)程秀撇,對(duì)比以往的代碼超棺,我們可以思考代碼結(jié)構(gòu)是否能設(shè)計(jì)得更加完善,邏輯函數(shù)是否清晰且考慮邊界條件呵燕,性能是否可以更加的優(yōu)化棠绘。

源自思否:https://segmentfault.com/a/1190000037762527?utm_source=tag-newest

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市再扭,隨后出現(xiàn)的幾起案子氧苍,更是在濱河造成了極大的恐慌,老刑警劉巖泛范,帶你破解...
    沈念sama閱讀 221,548評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件让虐,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡罢荡,警方通過(guò)查閱死者的電腦和手機(jī)澄干,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,497評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)柠傍,“玉大人,你說(shuō)我怎么就攤上這事辩稽【宓眩” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 167,990評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵逞泄,是天一觀的道長(zhǎng)患整。 經(jīng)常有香客問(wèn)我,道長(zhǎng)喷众,這世上最難降的妖魔是什么各谚? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,618評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮到千,結(jié)果婚禮上昌渤,老公的妹妹穿的比我還像新娘。我一直安慰自己憔四,他們只是感情好膀息,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,618評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布般眉。 她就那樣靜靜地躺著,像睡著了一般潜支。 火紅的嫁衣襯著肌膚如雪甸赃。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,246評(píng)論 1 308
  • 那天冗酿,我揣著相機(jī)與錄音埠对,去河邊找鬼。 笑死裁替,一個(gè)胖子當(dāng)著我的面吹牛项玛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播胯究,決...
    沈念sama閱讀 40,819評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼稍计,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了裕循?” 一聲冷哼從身側(cè)響起臣嚣,我...
    開(kāi)封第一講書(shū)人閱讀 39,725評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎剥哑,沒(méi)想到半個(gè)月后硅则,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,268評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡株婴,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,356評(píng)論 3 340
  • 正文 我和宋清朗相戀三年怎虫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片困介。...
    茶點(diǎn)故事閱讀 40,488評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡大审,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出座哩,到底是詐尸還是另有隱情徒扶,我是刑警寧澤,帶...
    沈念sama閱讀 36,181評(píng)論 5 350
  • 正文 年R本政府宣布根穷,位于F島的核電站姜骡,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏屿良。R本人自食惡果不足惜圈澈,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,862評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望尘惧。 院中可真熱鬧康栈,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,331評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至饥臂,卻和暖如春逊躁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背隅熙。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,445評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工稽煤, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人囚戚。 一個(gè)月前我還...
    沈念sama閱讀 48,897評(píng)論 3 376
  • 正文 我出身青樓酵熙,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親驰坊。 傳聞我的和親對(duì)象是個(gè)殘疾皇子匾二,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,500評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容