Vue全家桶實(shí)踐項(xiàng)目總結(jié)(推薦)

從前端的角度看,Vue可以說(shuō)是目前最理想的前端MVVM框架,一切為界面服務(wù),上手難度低,本文就將記錄使用Vue全家桶(Vue+Vue-router+Vuex)重構(gòu)一個(gè)jQuery+template項(xiàng)目的過(guò)程,以及期間的收獲。

句容網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司,句容網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為句容1000+提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站制作要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的句容做網(wǎng)站的公司定做!

入門

Vue的官方文檔就是學(xué)習(xí)Vue的最佳教程,沒(méi)有之一,可能因?yàn)榭蚣茏髡呤窃O(shè)計(jì)出身,沒(méi)有后端背景,因此各種抽象概念在Vue里都得以用最容易理解的方式被恰到好處的闡述,這里只簡(jiǎn)單介紹Vue、Vue-router、Vuex的概念,要全面學(xué)習(xí)建議去官方文檔。

Vue

Vue的核心功能是雙向綁定,可以自動(dòng)實(shí)現(xiàn)界面驅(qū)動(dòng)數(shù)據(jù)變化和數(shù)據(jù)驅(qū)動(dòng)界面變化,這能極大降低前端富交互應(yīng)用的開發(fā)成本。同類框架不止Vue一個(gè),但Vue的實(shí)現(xiàn)借助ES5原生特性,在性能方面有一定優(yōu)勢(shì)。

Vue-router

Vue-router是官方路由,用來(lái)組織url和組件間的映射關(guān)系,并自動(dòng)將url的變化響應(yīng)到組件中去,使開發(fā)者只需將關(guān)注點(diǎn)放在組件開發(fā)上,路由幫你解決相關(guān)的瑣碎問(wèn)題。

Vuex

Vuex提供一種集中式的數(shù)據(jù)管理模式,用以應(yīng)對(duì)數(shù)據(jù)流向復(fù)雜的情況,比如多個(gè)組件共用數(shù)據(jù)卻各自為營(yíng),可能導(dǎo)致該同步的數(shù)據(jù)沒(méi)有同步,或者由于js中Object對(duì)象的鉤子在內(nèi)存里指向同一實(shí)例,導(dǎo)致一旦操作原數(shù)據(jù)就會(huì)污染到其他組件,這時(shí)就需要一套更有條理的數(shù)據(jù)操作模式,那就是Vuex。

技術(shù)選型

跟jQuery對(duì)比

在了解了Vue的基本概念之后,肯定會(huì)不自覺(jué)的拿他們跟jQuery技術(shù)棧做對(duì)比,想知道這些東西對(duì)我的業(yè)務(wù)是否真的有必要。

首先MVVM解決的問(wèn)題能不能用jQuery解決?答案是肯定的,還記得最初做表單提交時(shí)用jQuery從一個(gè)一個(gè)的input里取值嗎?這就是界面驅(qū)動(dòng)數(shù)據(jù);如果做過(guò)任何異步交互功能的話,應(yīng)該都有過(guò)用jQuery將Ajax數(shù)據(jù)填充到界面中各個(gè)元素里的經(jīng)驗(yàn),這就是數(shù)據(jù)驅(qū)動(dòng)界面。雖然能做,但有點(diǎn)繁瑣,即便用上表單驗(yàn)證插件和前端模板引擎,也仍然需要在各個(gè)運(yùn)行節(jié)點(diǎn)手動(dòng)調(diào)用驗(yàn)證方法和渲染方法,做個(gè)網(wǎng)站頁(yè)面還好,可當(dāng)需求復(fù)雜到一定程度時(shí),這將是很大的負(fù)擔(dān)。

然后是路由,路由的本質(zhì)是通過(guò)操作url實(shí)現(xiàn)界面切換和界面保持,單頁(yè)面應(yīng)用必備,這個(gè)其實(shí)跟技術(shù)棧沒(méi)關(guān)系,只要產(chǎn)生了路由需求,即使是基于jQuery的項(xiàng)目也不過(guò)是再造了一個(gè)路由而已,只不過(guò)jQuery時(shí)代很少做單頁(yè)面應(yīng)用。

Vuex完全是基于雙向綁定延伸出來(lái)的東西,相當(dāng)于在數(shù)據(jù)和組件之間加了一個(gè)經(jīng)紀(jì)人,組件不能直接操作數(shù)據(jù),只能像經(jīng)紀(jì)人提交操作需求,由經(jīng)紀(jì)人去實(shí)施操作,以此解決人多手雜造成的各種不可預(yù)料的問(wèn)題,并且數(shù)據(jù)被從應(yīng)用中挪了出去,專門建立了一個(gè)Store,這樣就杜絕了組件之間數(shù)據(jù)污染的問(wèn)題。jQuery應(yīng)該說(shuō)不太會(huì)有這個(gè)需求,因?yàn)閖Query完全是手動(dòng)操作數(shù)據(jù),根本沒(méi)有意料之外的情況。

適用場(chǎng)景

經(jīng)過(guò)跟jQuery的對(duì)比之后,Vue的適用場(chǎng)景就很明顯了,從開發(fā)角度講交互越復(fù)雜的項(xiàng)目越適合,單頁(yè)面最適合,內(nèi)容類網(wǎng)站最不適合,如果網(wǎng)站中個(gè)別頁(yè)面有需求也可以局部使用,例如購(gòu)物車頁(yè)面。

當(dāng)然,這一切都要建立在不兼容IE8的前提下,對(duì)于這一點(diǎn)我有點(diǎn)疑惑,因?yàn)橐?jiàn)到有些2C的站點(diǎn)都在使用Vue,這些前端er是怎么把老板忽悠瘸的?

項(xiàng)目分析

項(xiàng)目背景

這次重構(gòu)的項(xiàng)目是為上一家公司開發(fā)的前端組件管理系統(tǒng),選擇重構(gòu)這個(gè)項(xiàng)目是因?yàn)閷?duì)需求比較熟悉,這是一個(gè)典型的單頁(yè)面應(yīng)用,而且復(fù)雜度適中,比較適合用作上手練習(xí)。

項(xiàng)目背景是外包類建站公司里,設(shè)計(jì)環(huán)節(jié)沉淀了大量可復(fù)用組件,設(shè)計(jì)師往往只需要微調(diào)組件就拼湊出頁(yè)面,交付給前端,理論上這些組件在前端也可以復(fù)用,但實(shí)際上前端每次都要重新實(shí)現(xiàn)整個(gè)頁(yè)面,浪費(fèi)很多人力。

功能需求

這個(gè)項(xiàng)目的思路是,將所有組件開發(fā)出來(lái),統(tǒng)一錄入到一個(gè)平臺(tái)上管理,設(shè)計(jì)師可以到平臺(tái)上挑選組件,并實(shí)時(shí)預(yù)覽和調(diào)整組件,整個(gè)過(guò)程所見(jiàn)即所得,平臺(tái)會(huì)將調(diào)整結(jié)果生成一串代碼,只要將代碼交給前端,就可以用這串代碼在平臺(tái)上重現(xiàn)設(shè)計(jì)師修改后的組件,并能一鍵復(fù)制組件的html/css/js代碼,快速應(yīng)用到項(xiàng)目中去,使組件部分的前端開發(fā)成本接近于零。平臺(tái)需要實(shí)現(xiàn)以下幾個(gè)功能:

  1. 管理組件,支持分類、搜索、排序
  2. 展示組件,支持組件在線預(yù)覽/編輯
  3. 組件交接,支持生成組件代碼和基于代碼重現(xiàn)組件
  4. 使用統(tǒng)計(jì),支持統(tǒng)計(jì)組件的使用情況,便于進(jìn)一步優(yōu)化組件

功能分析

第一版是用jQuery+template實(shí)現(xiàn)的,這個(gè)技術(shù)棧太靈活了,優(yōu)點(diǎn)是什么需求都好做,缺點(diǎn)是怎么做都行,不利于理清思路,往往伴隨著邊做邊改。

組件被統(tǒng)一放在一個(gè)widgets/文件夾里,被稱作組件庫(kù),因?yàn)槭羌兦岸隧?xiàng)目沒(méi)有文件操作能力,因此組件的讀取依賴一個(gè)靜態(tài)json文件,這個(gè)文件充當(dāng)組件庫(kù)的目錄,其中包括組件分類、標(biāo)簽、名稱、日期等所有信息,數(shù)據(jù)結(jié)構(gòu)大概是這樣:

[{
 "title": "導(dǎo)航類",
 "list": [{
 "widget": "bread-1",
 "title": "圖標(biāo)面包屑",
 "tag": "面包屑/圖標(biāo)",
 "author": "UI",
 "date": "2015-06-04"
 }, 
 ...]
},
...]

組件在組件庫(kù)中以欄目/編號(hào)二級(jí)文件夾的形式存放,同時(shí)約定用存放目錄作為組件代號(hào),例如組件bread-1意味著該組件存放地址是widgets/bread/1/文件夾。

當(dāng)然組件的內(nèi)部文件結(jié)構(gòu)也必須約定下來(lái),如下:

widgets
  |-bread
    |-1
      |-album.jpg   //縮略圖
      |-config.json  //配置文件
      |-script.js   //腳本模板
      |-style.css   //樣式模板
      `-temp.htm   //界面模板

有了這些約定,程序就可以通過(guò)目錄文件得到所有組件的信息,組件的獲取、展示、檢索也就可以實(shí)現(xiàn)了。

組件里最關(guān)鍵的是config.json文件,這里面包含該組件的可配置項(xiàng)及其默認(rèn)值,平臺(tái)在展示組件時(shí)會(huì)讀取這個(gè)配置文件,根據(jù)配置信息生成配置面板,這里面可以定義組件界面、樣式、腳本中的所有變量,配置文件大概長(zhǎng)這樣:

{
 "cssConfig": {
 "fontSize": {
  "name": "字號(hào)",
  "value": "12px",
  "type": "text"
 },
 ...
 },
 "jsConfig": {
    ...
 },
 "showConfig": {
 "viewWidth": {
  "name": "柵格寬度",
  "value": 12,
  "type": "number"
 },
 ...
 }
}

配置文件里的cssConfig、showConfig、jsConfig三個(gè)分支,就是組件中所有可以修改的變量集合,想將這些變量應(yīng)用到組件上,需要借助前端模板引擎,所以組件的三大件在開發(fā)的時(shí)候是用模板語(yǔ)法寫的,經(jīng)過(guò)模板引擎的解析,就能得到配置后的實(shí)際html/css/js內(nèi)容,例如樣式模板大概是這樣的:

.widget-bread-1 {
  font-size: ${fontSize.value}; 
  color: ${textColor.value}; 
}
.widget-bread-1 a { 
  color: ${textColor.value};
}
.widget-bread-1 a:hover{
  color:${hoverColor.value};
}
.widget-bread-1 .ion { 
  font-size: ${iconSize.value}; 
  margin: 0 ${iconMargin.value};
}

在得到組件實(shí)際代碼后,只要將結(jié)果插入頁(yè)面中并適時(shí)更新就行了,其中HTML和css可以直接替換文本內(nèi)容,js因?yàn)槭悄K化引入的,只替換模塊內(nèi)容不會(huì)重載模塊,必須將整個(gè)模塊重命名后進(jìn)行整體替換,因此js模塊的名稱是隨機(jī)的。

這里會(huì)有一個(gè)問(wèn)題,有的組件需要在頁(yè)面里多次使用,那么這個(gè)組件的js選擇器就會(huì)發(fā)生沖突,這個(gè)問(wèn)題的解決正好可以借助js模塊的那個(gè)隨機(jī)名稱,我們約定在組件開發(fā)中id作為保留變量,由平臺(tái)自動(dòng)賦值一個(gè)隨機(jī)字符串,這個(gè)字符串在組件實(shí)例內(nèi)部相同,多次調(diào)用則不同,這樣只要將${id}作為組件父節(jié)點(diǎn)的id或class,就解決了選擇器沖突問(wèn)題,同時(shí)也可以作為組件的css命名空間,使可能發(fā)生的css命名沖突也解決于無(wú)形。

以上是項(xiàng)目核心功能。

此外還用localStorage作為存儲(chǔ)方式實(shí)現(xiàn)了單機(jī)版的數(shù)據(jù)統(tǒng)計(jì),可以收集當(dāng)前瀏覽器的組件使用記錄,以及每個(gè)使用時(shí)的配置情況,這里主要是對(duì)本地存儲(chǔ)的操作,但是項(xiàng)目自身的開發(fā)也用到了前端模板,加上組件的模板,都會(huì)在第一次加載后用localStorage緩存起來(lái),這些內(nèi)容的緩存策略不同,用戶數(shù)據(jù)應(yīng)該是永久存儲(chǔ),項(xiàng)目模板應(yīng)該可以手動(dòng)更新,組件模板需要視情況而定,存儲(chǔ)的內(nèi)容多了就需要清理,清理的時(shí)候一條一條的去刪除就不現(xiàn)實(shí)了,全部刪除可能誤傷其他應(yīng)用的存儲(chǔ),這里的做法是將localStorage操作封裝,存儲(chǔ)方法會(huì)在在key前加上一個(gè)特殊前綴,刪除時(shí)只要遍歷本地存儲(chǔ)的key并且判斷是否匹配前綴就知道是否是應(yīng)用內(nèi)的存儲(chǔ)了,對(duì)應(yīng)的取值方法也要逆向的先給key加上前綴再去取值。

另外localStorage是只支持字符串存取的,為了方便我們存取對(duì)象類型,封裝方法還支持自動(dòng)轉(zhuǎn)換,但這個(gè)轉(zhuǎn)換還不能是盲目的遇到對(duì)象就轉(zhuǎn)字符,取值的時(shí)候匹配到可以轉(zhuǎn)對(duì)象就自動(dòng)轉(zhuǎn)了對(duì)象,因?yàn)橛袝r(shí)候用戶可能真的就存了一個(gè)對(duì)象字符串進(jìn)去,取出的時(shí)候也希望原樣拿回來(lái),要解決這個(gè)問(wèn)題需要做一個(gè)小hack,當(dāng)存儲(chǔ)方法檢測(cè)到值為對(duì)象時(shí),會(huì)轉(zhuǎn)成字符串然后在前面拼上一個(gè)標(biāo)識(shí)字符串,取值方法只有在檢測(cè)到這個(gè)標(biāo)識(shí)后才會(huì)將后面的字符串還原成對(duì)象,這種方式雖然可以滿足需求,但不是很保險(xiǎn),因?yàn)檫@個(gè)前綴是固定的,理論上總是有可能遇到中獎(jiǎng)的,不知道這個(gè)問(wèn)題還有沒(méi)有其他的更優(yōu)解。

項(xiàng)目的主要功能點(diǎn)就是這些。

重構(gòu)

一次重構(gòu)

第一次重構(gòu)只用了Vue,重構(gòu)過(guò)程中首先體會(huì)到的是各種便捷,本來(lái)要調(diào)用模板引擎做的事框架順便就做了,本來(lái)要在js里綁定事件現(xiàn)在模板里直接可以綁定,還有其他各種語(yǔ)法糖。

當(dāng)然,最重要的還是雙向綁定,基于雙向綁定可以讓界面和數(shù)據(jù)自動(dòng)的關(guān)聯(lián)起來(lái),讓人感覺(jué)程序具有了一定的自主能動(dòng)性,但為了讓這種自主性正常運(yùn)轉(zhuǎn),開發(fā)者必須事先規(guī)劃好每一步路,這相對(duì)jQuery來(lái)說(shuō)就會(huì)顯得不那么自由。拿搬磚頭舉例,jQuery好比一個(gè)特別靈活的起重機(jī),可以舉重若輕,可以花式搬磚;Vue則像一個(gè)萬(wàn)能遙控器,你告訴他你要把磚頭從某地搬到某地,期間發(fā)生什么情況要如何處理,按動(dòng)按鈕就可以自動(dòng)搬磚了。

兩種方式各有優(yōu)劣,起重機(jī)開的好可以很靈活,路上遇到坑容易躲避,缺點(diǎn)是你要一趟一趟的開它;按鈕可以一次編程自動(dòng)運(yùn)行,缺點(diǎn)是你必須事先把路上的坑實(shí)地考察好,把別的車全部調(diào)度好,所有的情況說(shuō)清楚,否則就會(huì)翻車或撞車,從jQuery轉(zhuǎn)到Vue一定會(huì)感覺(jué)到這種束縛感,逼的你必須”謀而后動(dòng)”,不能先上車再說(shuō)。

重構(gòu)期間很大一部分工作就是建立Vue實(shí)例,將散布在js各個(gè)角落的數(shù)據(jù)收集到data中去,將操作數(shù)據(jù)的過(guò)程一點(diǎn)一點(diǎn)的集中到methods中去,將數(shù)據(jù)的篩選過(guò)程集中到computed中去,這整個(gè)過(guò)程可以清晰的回顧每一個(gè)實(shí)現(xiàn)細(xì)節(jié),反思每一個(gè)實(shí)現(xiàn)方式是不是合理,其實(shí)也就是將原來(lái)開起重機(jī)的過(guò)程歸納成一個(gè)一個(gè)的遙控器按鈕,當(dāng)全部歸納完成后,Vue示例也就變成了最終我們的項(xiàng)目,能夠自動(dòng)運(yùn)行。

經(jīng)過(guò)重構(gòu),依托Vue的各種功能使邏輯部分的代碼量減少了,除此之外對(duì)項(xiàng)目本身來(lái)說(shuō)并沒(méi)有什么改進(jìn),因?yàn)闆](méi)有路由所以刷新頁(yè)面狀態(tài)丟失問(wèn)題仍然存在;因?yàn)闆](méi)有使用Vuex還遇到一個(gè)數(shù)據(jù)污染的坑,只能用深拷貝解決;并且基于組件的開發(fā)模式,讓代碼組織更零碎了,這些問(wèn)題都需要二次重構(gòu)。

二次重構(gòu)

二次重構(gòu)目標(biāo)是完善路由、Vuex、代碼組織、野狗云后端。

雖然有了第一次重構(gòu)的經(jīng)驗(yàn),但二次重構(gòu)一開始還是有點(diǎn)茫然,路由和Vuex應(yīng)該先上哪一個(gè)?想了想,路由做的事是”拆”,Vuex做的事是”改”,感覺(jué)改完再拆的工作量會(huì)小一點(diǎn),所以先上Vuex。

Vuex的概念憑空理解有點(diǎn)抽象,一旦用上卻覺(jué)得的得心應(yīng)手,而且這個(gè)東西不像路由,幾乎不需要區(qū)分場(chǎng)景都可以用,引入Vuex后數(shù)據(jù)污染的問(wèn)題自然就解決了,而且Vuex帶來(lái)的 action => mutation => store 流程一旦接受了真的會(huì)讓事情變簡(jiǎn)單,引入Vuex的過(guò)程基本就是將data轉(zhuǎn)移到store,將數(shù)據(jù)操作分散到actions,getters,mutations中去,同時(shí)很多同步數(shù)據(jù)操作都不需要了,從而使代碼量又減少了一些。

之后開始引入路由,一開始拿不準(zhǔn)應(yīng)該怎么劃分視圖,大的視圖肯定是登錄、注冊(cè)、主界面,問(wèn)題是主界面需不需要再細(xì)分,理論上可以分的很細(xì),但結(jié)合應(yīng)用實(shí)際使用場(chǎng)景發(fā)現(xiàn),界面的切換相對(duì)頻繁,組件頻繁載入和卸載的開銷會(huì)很大,而且將耦合緊密的組件拆到不同的視圖,需要記錄很多狀態(tài)信息,有點(diǎn)得不償失,最終作罷,沒(méi)有將主視圖繼續(xù)分下去。考慮到三個(gè)視圖的訪問(wèn)重疊性不高,自然就需要將組件做成異步加載,只在訪問(wèn)到的時(shí)候才加載組件,Vue自身支持異步組件,所以這件事變得非常簡(jiǎn)單,只要能返回一個(gè)Promise,你可以使用任意方式獲取組件。

接下來(lái)要接入野狗云,實(shí)現(xiàn)真正的用戶管理和數(shù)據(jù)統(tǒng)計(jì),野狗云可以提供用戶鑒權(quán)和數(shù)據(jù)存儲(chǔ)等一系列功能,通過(guò)它只需要用js就可以開發(fā)一個(gè)完整的WEB應(yīng)用。這樣之前所有對(duì)localStorage的操作都要改成對(duì)野狗云的操作,數(shù)據(jù)到了云端也變得更可靠了。

至此二次重構(gòu)就完成了,業(yè)務(wù)代碼總體感覺(jué)減少了很多,但總代碼量估計(jì)沒(méi)少多少,畢竟還增加了三個(gè)框架文件,不過(guò)經(jīng)過(guò)重重拆分,文件數(shù)量從當(dāng)初的三兩個(gè)js變成了十來(lái)個(gè)js,模塊化方面用的seajs而不是webpack,因?yàn)閭€(gè)人對(duì) webpack仍然持觀望態(tài)度,目前還感覺(jué)不到用它的必要性,關(guān)鍵是基于webpack開發(fā)的代碼會(huì)夾雜很多私貨,讓你的代碼變得不原生,離了他就運(yùn)行不起來(lái),這個(gè)我不太能接受,而且在多頁(yè)面場(chǎng)景seajs配合本地緩存比webpack更有優(yōu)勢(shì),當(dāng)然了,他們的的區(qū)別就跟jQuery和Vue的區(qū)別一樣,本質(zhì)不是一個(gè)東西,關(guān)鍵在于使用場(chǎng)景,適合的就是最好的。

后記

經(jīng)過(guò)兩次重構(gòu)的實(shí)踐和踩坑,對(duì)Vue框架有了更深刻的認(rèn)識(shí),Vue想要用的靈活自如,對(duì)開發(fā)者的項(xiàng)目架構(gòu)能力有一個(gè)最低要求,如果要將Vue引入底層,對(duì)基礎(chǔ)設(shè)施建設(shè)者的規(guī)劃能力也有一個(gè)最低要求,這些都是jQuery技術(shù)棧所不存在的,使用Vue的過(guò)程也是接受這些約束的過(guò)程,他們能引導(dǎo)開發(fā)者建立自己的規(guī)則體系,這是好事也是大勢(shì)所趨,畢竟真正的自由只存在于規(guī)則中。

本文的完整代碼見(jiàn)Github。

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持創(chuàng)新互聯(lián)。

當(dāng)前文章:Vue全家桶實(shí)踐項(xiàng)目總結(jié)(推薦)
網(wǎng)站URL:http://bm7419.com/article18/igeedp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信公眾號(hào)、移動(dòng)網(wǎng)站建設(shè)、手機(jī)網(wǎng)站建設(shè)域名注冊(cè)、外貿(mào)建站、小程序開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

網(wǎng)站托管運(yùn)營(yíng)