摘要:將注意力集中保持在核心庫(kù),而將其他功能如路由和全局狀態(tài)管理交給相關(guān)的庫(kù)。此示例使用類(lèi)似的語(yǔ)法,稱(chēng)為。執(zhí)行更快,因?yàn)樗诰幾g為代碼后進(jìn)行了優(yōu)化?;诘哪0迨沟脤⒁延械膽?yīng)用逐步遷移到更為容易。
前言
因?yàn)闆](méi)有明確的界定,這里不討論正確與否,只表達(dá)個(gè)人對(duì)前端MV*架構(gòu)模式理解看法,再比較React和Vue兩種框架不同.
寫(xiě)完之后我知道這文章好水,特別是框架對(duì)比部分都是別人說(shuō)爛的,而我也是打算把這作為長(zhǎng)期文章來(lái)寫(xiě),慢慢梳理深入,每次有新的理解就更新文章,我挺期待之后到了超過(guò)字?jǐn)?shù)限制不得不寫(xiě)成系列文章的那一天.
2018/04/28 新增聲明式渲染 && 生命周期對(duì)比 && 狀態(tài)(State) OR 屬性(Data) && Props組件通信
2018/05/02 新增狀態(tài)管理
2018/06/07 新增mobx狀態(tài)管理
2018/11/06 補(bǔ)充更新機(jī)制和狀態(tài)管理對(duì)比
MVC全名是Model View Controller,把應(yīng)用程序分成三部分分別是:
Model(業(yè)務(wù)模型): 用于管理應(yīng)用程序數(shù)據(jù)處理邏輯的部分,通過(guò)觀察者模式(Pub&Sub / Events)發(fā)送消息給View;
View(視圖界面): 用于處理數(shù)據(jù)顯示的部分,注冊(cè)并接收Model的數(shù)據(jù)更新視圖,通常視圖是依據(jù)模型數(shù)據(jù)創(chuàng)建的;
Controller(控制器): 用于連接模型和視圖控制應(yīng)用程序的流程(事件綁定等),通??刂破髫?fù)責(zé)響應(yīng)View的事件(路由,鍵盤(pán),鼠標(biāo)等),調(diào)用Model的接口進(jìn)行操作;
(這些簡(jiǎn)單的東西我就懶得特意畫(huà)圖了,直接百度圖片找張清晰的拿來(lái)用的..)
(更多內(nèi)容請(qǐng)自行查閱,本節(jié)到此為止了.)
當(dāng)用戶(hù)在視圖界面中發(fā)生交互事件,View捕獲到這個(gè)操作會(huì)把處理的權(quán)利交移給Controller;
Controller會(huì)對(duì)來(lái)自View數(shù)據(jù)進(jìn)行預(yù)處理并決定調(diào)用Model的相關(guān)暴露接口;
Model執(zhí)行相關(guān)的業(yè)務(wù)邏輯更改數(shù)據(jù)之后會(huì)通知有關(guān)的View重新渲染;
View收到通知后從Model請(qǐng)求最新的數(shù)據(jù),然后重新渲染相關(guān)視圖界面;
還有一種情況: MVC允許在不改變視圖外觀的情況下改變視圖對(duì)用戶(hù)輸入的響應(yīng)方式,只要用不同種類(lèi)的controller實(shí)例替換即可。例如改變URL觸發(fā)hashChange事件,用戶(hù)不經(jīng)過(guò)View直接到達(dá)Controller最后再影響回View.
優(yōu)點(diǎn):耦合性低,MVC 分層有助于管理復(fù)雜的應(yīng)用程序,同時(shí)也讓?xiě)?yīng)用程序的測(cè)試更加容易;
重用性高,多個(gè)視圖能共享一個(gè)模型,可以做到多視圖同時(shí)更新;
生命周期成本低,MVC使開(kāi)發(fā)和維護(hù)用戶(hù)接口的技術(shù)含量降低;
部署快,只需要部署對(duì)應(yīng)部分代碼而不是完整項(xiàng)目;
可維護(hù)性高,分離視圖層和業(yè)務(wù)邏輯層也使得應(yīng)用更易于維護(hù)和修改;
有利軟件工程化管理,可以使用控制器來(lái)聯(lián)接不同的模型和視圖去完成用戶(hù)的需求;
缺點(diǎn):沒(méi)有明確的定義,完全理解MVC并不是很容易,現(xiàn)存就有很多對(duì)MVC不同解讀實(shí)現(xiàn)的方式;
不適合小型,中等規(guī)模的應(yīng)用程序,花費(fèi)大量時(shí)間將MVC應(yīng)用到規(guī)模并不是很大的應(yīng)用程序通常會(huì)得不償失;
增加系統(tǒng)結(jié)構(gòu)和實(shí)現(xiàn)的復(fù)雜性,對(duì)于簡(jiǎn)單的界面,會(huì)增加結(jié)構(gòu)的復(fù)雜性,并可能產(chǎn)生過(guò)多的更新操作,降低運(yùn)行效率;
視圖與控制器間的過(guò)于緊密的連接,視圖沒(méi)有控制器的存在,其應(yīng)用是很有限的,反之亦然,導(dǎo)致測(cè)試?yán)щy(依據(jù)模型數(shù)據(jù)創(chuàng)建部分);
視圖對(duì)模型數(shù)據(jù)的低效率訪(fǎng)問(wèn),依據(jù)模型操作接口的不同,視圖可能需要多次調(diào)用才能獲得足夠的顯示數(shù)據(jù);
觀察者模式由于事件觸發(fā)的隱式行為可能導(dǎo)致很難查找問(wèn)題的來(lái)源并影響其解決;
MVPMVP全名是Model-View-Presenter,從經(jīng)典的模式MVC演變而來(lái),分兩種情況:
Passive View(被動(dòng)視圖)Presenter占據(jù)絕對(duì)主導(dǎo)地位,掌控著Model和View,而后兩者之間互不聯(lián)系.
Model(業(yè)務(wù)模型): 用于管理應(yīng)用程序數(shù)據(jù)處理邏輯的部分,通過(guò)觀察者模式(Pub&Sub / Events)發(fā)送消息給Presenter;
View(視圖界面): 用于處理數(shù)據(jù)顯示的部分,傳遞事件和提供相關(guān)接口給Presenter;
Presenter(派發(fā)器): 作為中間層同步控制著Model數(shù)據(jù)修改和View視圖變化;
(這些簡(jiǎn)單的東西我就懶得特意畫(huà)圖了,直接百度圖片找張清晰的拿來(lái)用的..)
(更多內(nèi)容請(qǐng)自行查閱,本節(jié)到此為止了.)
當(dāng)用戶(hù)在視圖界面中發(fā)生交互事件,View捕獲到這個(gè)操作會(huì)把處理的權(quán)利交移給Presenter進(jìn)行處理;
Presenter需要時(shí)候可以獲取Model其中的數(shù)據(jù),并對(duì)Model進(jìn)行操作更新;
Model數(shù)據(jù)變化之后會(huì)通知Presenter;
Presenter收到通知后會(huì)執(zhí)行View提供的相關(guān)接口重新渲染相關(guān)視圖界面;
MVC和MVP(Passive View)區(qū)別:后者View和Model完全解耦,它們之間的通信是通過(guò)Presenter (MVC中的Controller)來(lái)進(jìn)行的,所有的交互都發(fā)生在Presenter內(nèi)部;
前者Controller只能通過(guò)Model間接觸發(fā)View自行更新視圖,后者View不再負(fù)責(zé)更新視圖,而是提供接口給Presenter執(zhí)行;
Supervising Controller(監(jiān)督控制器)Presenter依舊占據(jù)主導(dǎo)地位,但是會(huì)把一部分簡(jiǎn)單的視圖邏輯(如雙向綁定)交還給View和Model進(jìn)行處理,自身負(fù)責(zé)其他復(fù)雜的視圖邏輯.
Model(業(yè)務(wù)模型): 用于管理應(yīng)用程序數(shù)據(jù)處理邏輯的部分,通過(guò)觀察者模式(Pub&Sub / Events)發(fā)送消息給Presenter或者View;
View(視圖界面): 用于處理數(shù)據(jù)顯示的部分和接管部分簡(jiǎn)單的視圖邏輯,同步簡(jiǎn)單的視圖和模型的狀態(tài),傳遞事件和提供相關(guān)接口給Presenter;
Presenter(派發(fā)器): 作為中間層同步控制著Model數(shù)據(jù)修改和View視圖變化;
MVC和MVP(Supervising Controller)區(qū)別:
1, 視圖支持Presenter和View兩種途徑更新;
1, 模型與視圖高度分離,我們可以修改視圖而不影響模型;
2, 可以更高效地使用模型,因?yàn)樗械慕换ザ及l(fā)生在一個(gè)地方——Presenter內(nèi)部;
3, 可以將一個(gè)Presenter用于多個(gè)視圖,而不需要改變Presenter的邏輯;
4, 如果把邏輯放在Presenter中,就可以脫離用戶(hù)接口來(lái)測(cè)試這些邏輯(單元測(cè)試);
1, 由于對(duì)視圖的渲染放在了Presenter中,所以View和Presenter的交互會(huì)過(guò)于頻繁并且難以維護(hù);
MVVMMVVM全名是Model-View-ViewModel,本質(zhì)上就是MVC的改進(jìn)版,也可以說(shuō)是MVP的改良版,把應(yīng)用程序分成三部分分別是:
Model(業(yè)務(wù)模型): 用于管理應(yīng)用程序數(shù)據(jù);
View(視圖界面): 通過(guò)使用模板語(yǔ)法來(lái)聲明式的將數(shù)據(jù)渲染進(jìn)DOM;
ViewModel(視圖模型): 包含了領(lǐng)域模型(Domain Model)和視圖的狀態(tài)(State),核心就是雙向綁定技術(shù)(Two-Way-Data-Binding),View和Model之間數(shù)據(jù)同步操作交由給內(nèi)部的Binder/Data-binding engine處理;
MVP和MVVM區(qū)別: 它使用 數(shù)據(jù)綁定(Data Binding)、依賴(lài)屬性(Dependency Property)、命令(Command)、路由事件(Routed Event) 來(lái)搞定與view層的交互, 當(dāng)ViewModel對(duì)Model進(jìn)行更新的時(shí)候,會(huì)通過(guò)數(shù)據(jù)綁定更新到View.
(這些簡(jiǎn)單的東西我就懶得特意畫(huà)圖了,直接百度圖片找張清晰的拿來(lái)用的..)
(更多內(nèi)容請(qǐng)自行查閱,本節(jié)到此為止了.)
雙向綁定(data-binding):View的變動(dòng),自動(dòng)反映在 ViewModel,反之亦然;
解放MVP大量手動(dòng)同步狀態(tài)的問(wèn)題,提高了代碼的可維護(hù)性;
簡(jiǎn)化測(cè)試,Model正確就能保證View輸出;
缺點(diǎn):大型項(xiàng)目的綁定數(shù)據(jù)較多會(huì)提高維護(hù)成本;
View里的數(shù)據(jù)綁定無(wú)法檢測(cè)斷點(diǎn),只能從Model下手;
React VS Vue兩個(gè)框架是現(xiàn)在最熱門(mén)的選擇之一,它們既類(lèi)似又不同.
使用 Virtual DOM
提供了響應(yīng)式 (Reactive) 和組件化 (Composable) 的視圖組件。
將注意力集中保持在核心庫(kù),而將其他功能如路由和全局狀態(tài)管理交給相關(guān)的庫(kù)。
React就是MVC里的V,只專(zhuān)注視圖層,而Vue算是MVVM框架,雙向綁定是特色之一.
介紹我們先看看它們自己的官方介紹:
ReactReact is a JavaScript library for building user interfaces.
Declarative: React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes. Declarative views make your code more predictable, simpler to understand, and easier to debug.
Component-Based: Build encapsulated components that manage their own state, then compose them to make complex UIs. Since component logic is written in JavaScript instead of templates, you can easily pass rich data through your app and keep state out of the DOM.
Learn Once, Write Anywhere: We don"t make assumptions about the rest of your technology stack, so you can develop new features in React without rewriting existing code. React can also render on the server using Node and power mobile apps using React Native.
翻譯:React是一個(gè)用于構(gòu)建用戶(hù)界面的Javascript庫(kù).
聲明式: React讓你無(wú)痛創(chuàng)建交互式UI界面,為你的App應(yīng)用程序里的每個(gè)狀態(tài)設(shè)計(jì)簡(jiǎn)單的視圖,并且當(dāng)你的數(shù)據(jù)改變之后會(huì)進(jìn)行高效地更新和正確地渲染對(duì)應(yīng)組件,聲明式視圖讓你的代碼更可預(yù)測(cè)、更易于理解和更容易調(diào)試.
組件化: 構(gòu)建封裝組件管理它們自己的內(nèi)部狀態(tài),然后組合它們?nèi)?gòu)建復(fù)雜UI界面.因?yàn)榻M件邏輯寫(xiě)在Javascript而不是模板里,你能輕松注入豐富的數(shù)據(jù)到你的App并且狀態(tài)脫離在Dom之外.
只需學(xué)習(xí)一次,就能用到任何地方,我們不對(duì)你的其余技術(shù)棧作出假設(shè),所以你能在React里開(kāi)發(fā)新的特性而不需要重寫(xiě)你的現(xiàn)有代碼.React也能使用Nodejs進(jìn)行服務(wù)器渲染和使用React Native進(jìn)行移動(dòng)端的豐富開(kāi)發(fā).
VueVue (pronounced /vju?/, like view) is a progressive framework for building user interfaces. Unlike other monolithic frameworks, Vue is designed from the ground up to be incrementally adoptable. The core library is focused on the view layer only, and is easy to pick up and integrate with other libraries or existing projects. On the other hand, Vue is also perfectly capable of powering sophisticated Single-Page Applications when used in combination with modern tooling and supporting libraries.
翻譯:Vue.js (讀音 /vju?/,類(lèi)似于 view) 是一套構(gòu)建用戶(hù)界面的漸進(jìn)式框架。與其他重量級(jí)框架不同的是,Vue 采用自底向上增量開(kāi)發(fā)的設(shè)計(jì)。Vue 的核心庫(kù)只關(guān)注視圖層,它不僅易于上手,還便于與第三方庫(kù)或既有項(xiàng)目整合。另一方面,當(dāng)與單文件組件和 Vue 生態(tài)系統(tǒng)支持的庫(kù)結(jié)合使用時(shí),Vue 也完全能夠?yàn)閺?fù)雜的單頁(yè)應(yīng)用程序提供驅(qū)動(dòng)。
聲明式渲染 React(官方寫(xiě)法)React 組件實(shí)現(xiàn)一個(gè) render() 方法,它接收輸入數(shù)據(jù)并返回顯示的內(nèi)容。此示例使用類(lèi)似XML的語(yǔ)法,稱(chēng)為 JSX 。輸入數(shù)據(jù)可以通過(guò) this.props 傳入組件,被 render() 訪(fǎng)問(wèn)。
class HelloMessage extends React.Component { render() { return (Vue(官方寫(xiě)法)Hello {this.props.name}); } } ReactDOM.render(, mountNode );
Vue.js 的核心是一個(gè)允許采用簡(jiǎn)潔的模板語(yǔ)法來(lái)聲明式的將數(shù)據(jù)渲染進(jìn) DOM 的系統(tǒng)
HTML React JSX{{ message }}// --------省略-------- var app = new Vue({ el: "#app", data: { message: "Hello Vue!" } })
他是 JavaScrip 的一種擴(kuò)展語(yǔ)法。 React 官方推薦使用這種語(yǔ)法來(lái)描述 UI 信息。JSX 可能會(huì)讓你想起某種模板語(yǔ)言,但是它具有 JavaScrip 的全部能力,從本質(zhì)上講,JSX 只是為 React.createElement(component, props, ...children) 函數(shù)提供的語(yǔ)法糖。
JSX 執(zhí)行更快,因?yàn)樗诰幾g為 JavaScript 代碼后進(jìn)行了優(yōu)化。
它是類(lèi)型安全的,在編譯過(guò)程中就能發(fā)現(xiàn)錯(cuò)誤。
使用 JSX 編寫(xiě)模板更加簡(jiǎn)單快速。
JSX 對(duì)使用React 不是必須的。
Vue TemplatesVue.js 使用了基于 HTML 的模板語(yǔ)法,允許開(kāi)發(fā)者聲明式地將 DOM 綁定至底層 Vue 實(shí)例的數(shù)據(jù)。所有 Vue.js 的模板都是合法的 HTML ,所以能被遵循規(guī)范的瀏覽器和 HTML 解析器解析。
在底層的實(shí)現(xiàn)上,Vue 將模板編譯成虛擬 DOM 渲染函數(shù)。結(jié)合響應(yīng)系統(tǒng),在應(yīng)用狀態(tài)改變時(shí),Vue 能夠智能地計(jì)算出重新渲染組件的最小代價(jià)并應(yīng)用到 DOM 操作上。
事實(shí)上 Vue 也提供了渲染函數(shù),甚至支持 JSX。然而,默認(rèn)推薦的還是模板。
對(duì)于很多習(xí)慣了 HTML 的開(kāi)發(fā)者來(lái)說(shuō),模板比起 JSX 讀寫(xiě)起來(lái)更自然。這里當(dāng)然有主觀偏好的成分,但如果這種區(qū)別會(huì)導(dǎo)致開(kāi)發(fā)效率的提升,那么它就有客觀的價(jià)值存在。
基于 HTML 的模板使得將已有的應(yīng)用逐步遷移到 Vue 更為容易。
這也使得設(shè)計(jì)師和新人開(kāi)發(fā)者更容易理解和參與到項(xiàng)目中。
你甚至可以使用其他模板預(yù)處理器,比如 Pug 來(lái)書(shū)寫(xiě) Vue 的模板。
對(duì)比個(gè)人感覺(jué)兩者其實(shí)上手速度都挺快,相比之下JSX除了修改部分屬性名字跟普通HTML變化不算大,Templates額外添加很多自定義功能幫助開(kāi)發(fā)者做更多的事,框架痕跡也比較重.
我們可以把組件區(qū)分為兩類(lèi):一類(lèi)是偏視圖表現(xiàn)的 (presentational)推薦使用模板,一類(lèi)則是偏邏輯的 (logical)推薦使用 JSX 或渲染函數(shù)。
//Jsx寫(xiě)法{ todos.map(item =>
- {todo.text}
) }
//Templates寫(xiě)法CSS React
- {{ todo.text }}
React 中推薦通過(guò) CSS-in-JS 的方案實(shí)現(xiàn)的 (比如 styled-components、glamorous 和 emotion),雖然在構(gòu)建時(shí)將 CSS 提取到一個(gè)多帶帶的樣式表是支持的,但 bundle 里通常還是需要一個(gè)運(yùn)行時(shí)程序來(lái)讓這些樣式生效。當(dāng)你能夠利用 JavaScript 靈活處理樣式的同時(shí),也需要權(quán)衡 bundle 的尺寸和運(yùn)行時(shí)的開(kāi)銷(xiāo)
var styleObj = { color:"blue", fontSize:40, fontWeight:"normal" }; --------省略--------VueHello
Vue 設(shè)置樣式的默認(rèn)方法是單文件組件里類(lèi)似 style 的標(biāo)簽。讓你可以在同一個(gè)文件里完全控制 CSS,將其作為組件代碼的一部分。
這個(gè)可選 scoped 屬性會(huì)自動(dòng)添加一個(gè)唯一的屬性 (比如 data-v-21e5b78) 為組件內(nèi) CSS 指定作用域,編譯的時(shí)候 .list-container:hover 會(huì)被編譯成類(lèi)似 .list-container[data-v-21e5b78]:hover。
最后,Vue 的單文件組件里的樣式設(shè)置是非常靈活的。通過(guò) vue-loader,你可以使用任意預(yù)處理器、后處理器,甚至深度集成 CSS Modules——全部都在