大前端的概念一而再再而三的被提及,那么大前端時(shí)代究竟是什么呢?大前端這個(gè)詞最早是因?yàn)樵诎⒗飪?nèi)部有很多前端開(kāi)發(fā)人員既寫(xiě)前端又寫(xiě) Java 的 Velocity 模板而得來(lái),不過(guò)現(xiàn)在大前端的范圍已經(jīng)越來(lái)越大了,包含前端 + 移動(dòng)端,前端、CDN、Nginx、Node、Hybrid、Weex、React Native、Native App。筆者是一名普通的全職 iOS 開(kāi)發(fā)者,在接觸到了前端開(kāi)發(fā)以后,發(fā)現(xiàn)了前端有些值得移動(dòng)端學(xué)習(xí)的地方,于是便有了這個(gè)大前端時(shí)代系列的文章,希望兩者能相互借鑒優(yōu)秀的思想。談及到大前端,常常被提及的話題有:組件化,路由與解耦,工程化(打包工具,腳手架,包管理工具),MVC 和 MVVM 架構(gòu),埋點(diǎn)和性能監(jiān)控。筆者就先從組件化方面談起。網(wǎng)上關(guān)于前端框架對(duì)比的文章也非常多(對(duì)比 React,Vue,Angular),不過(guò)跨端對(duì)比的文章好像不多?筆者就打算以前端和移動(dòng)端(以 iOS 平臺(tái)為主)對(duì)比為主,看看這兩端的不同做法,并討論討論有無(wú)相互借鑒學(xué)習(xí)的地方。
一. 組件化的需求
為了提高代碼復(fù)用性,減少重復(fù)性的開(kāi)發(fā),我們就把相關(guān)的代碼按照 ?template、style、script 拆分,封裝成一個(gè)個(gè)的組件。組件可以擴(kuò)展
HTML 元素,封裝可重用的 HTML 代碼,我們可以將組件看作自定義的 HTML 元素。在 Vue 里面,每個(gè)封裝好的組件可以看成一個(gè)個(gè)的 ViewModel。
二. 如何封裝組件
談到如何封裝的問(wèn)題,就要先說(shuō)說(shuō)怎么去組織組件的問(wèn)題。
如果在簡(jiǎn)單的 SPA 項(xiàng)目中,可以直接用 Vue.component 去定義一個(gè)全局組件,項(xiàng)目一旦復(fù)雜以后,就會(huì)出現(xiàn)弊端了:
- 全局定義(Global definitions) 強(qiáng)制要求每個(gè) component 中的命名不得重復(fù)
- 字符串模板(String templates) 缺乏語(yǔ)法高亮,在 HTML 有多行的時(shí)候,需要用到丑陋的 \
- 不支持 CSS(No CSS support) 意味著當(dāng) HTML 和 JavaScript 組件化時(shí),CSS 明顯被遺漏
- 沒(méi)有構(gòu)建步驟(No build step) 限制只能使用 HTML 和 ES5 JavaScript, 而不能使用預(yù)處理器,如 Pug (formerly Jade) 和 Babel
而且現(xiàn)在公司級(jí)的項(xiàng)目,大多數(shù)都會(huì)引入工程化的管理,用包管理工具去管理,npm 或者 yarn。所以 Vue 在復(fù)雜的項(xiàng)目中用 Vue.component 去定義一個(gè)組件的方式就不適合了。這里就需要用到單文件組件,還可以使用 Webpack 或 Browserify 等構(gòu)建工具。比如下面這個(gè)Hello.vue組件,整個(gè)文件就是一個(gè)組件。
在單文件組件中,整個(gè)文件都是一個(gè) CommonJS 模塊,里面包含了組件對(duì)應(yīng)的 HTML、組件內(nèi)的處理邏輯 Javascript、組件的樣式 CSS。
在組件的 script 標(biāo)簽中,需要封裝該組件 ViewModel 的行為。
- data
組件的初始化數(shù)據(jù),以及私有屬性。
- props
組件的屬性,這里的屬性專(zhuān)門(mén)用來(lái)接收父子組件通信的數(shù)據(jù)。(這里可以類(lèi)比 iOS 里面的 @property )
- methods
組件內(nèi)的處理邏輯函數(shù)。
- watch
需要額外監(jiān)聽(tīng)的屬性(這里可以類(lèi)比 iOS 里面的 KVO )
- computed
組件的計(jì)算屬性
- components
所用到的子組件
- lifecycle hooks
生命周期的鉤子函數(shù)。一個(gè)組件也是有生命周期的,有如下這些:beforeCreate、created、beforeMount、mounted、beforeUpdate、updated、activated、deactivated、beforeDestroy、destroyed等生命周期。在這些鉤子函數(shù)里面可以加上我們預(yù)設(shè)的處理邏輯。(這里可以類(lèi)比 iOS 里面的 ViewController 的生命周期 )
如此看來(lái),在 Vue 里面封裝一個(gè)單文件組件,和在 iOS 里面封裝一個(gè) ViewModel 的思路是完全一致的。接下來(lái)的討論無(wú)特殊說(shuō)明,針對(duì)的都是單文件組件。
三. 如何劃分組件
一般劃分組件分可以按照以下標(biāo)準(zhǔn)去劃分:
- 頁(yè)面區(qū)域:
header、footer、sidebar……
- 功能模塊:
select、pagination……
?