三大前端技術(React,Vue,Angular)探密
【引言】
本文就對于當下頂級的前端開發技術做個相對詳盡的探究,目的是為了解開這些前端技術的面紗,看看各自的廬山真面目。
【React】
React(也被稱為React.js或ReactJS)是一個用于構建用戶界面的JavaScript庫。它由Facebook和一個由個人開發者和公司組成的社區來維護。
React可以作為開發單頁或移動應用的基礎。然而,React只關注向DOM渲染數據,因此創建React應用通常需要使用額外的庫來進行狀態管理和路由,Redux和React Router分別是這類庫的例子。
基本用法
下面是一個簡單的React在HTML中使用JSX和JavaScript的例子。
function?Greeter(props)?{
return?
{props.greeting}
;}
var?App?=?
ReactDOM.render(App,?document.getElementById("myReactApp"));
Greeter函數是一個React組件,它接受一個屬性問候語。變量App是Greeter組件的一個實例,其中問候語屬性被設置為?"Hello World!"。然后,ReactDOM.render方法將我們的Greeter組件渲染在DOM元素(id為?myReactApp)中。
在web瀏覽器中顯示時,結果將是:
Hello?World!
顯著特點
組件化
React代碼由稱為組件的實體組成。組件可以使用React DOM庫渲染到DOM中的一個特定元素。當渲染一個組件時,可以傳入被稱為?"props "的值。
ReactDOM.render(
React中聲明組件的兩種主要方式是通過功能函數組件和基于類的組件。
功能函數組件
功能組件是用一個函數聲明,用來返回一些JSX。
const?Greeting?=?(props)?=>?
類組件
基于類的組件是使用ES6類來聲明的。它們也被稱為?"有狀態?"組件,因為它們的狀態可以在整個組件中保持,并且可以通過props傳遞給子組件。
class?ParentComponent?extends?React.Component?{
state?=?{?color:?'green'?};
render()?{
return?(
);
}
}
虛擬?DOM
另一個值得注意的特點是React使用了虛擬文檔對象模型,也就是虛擬DOM。React創建了一個內存中的數據結構緩存,計算得出變化差異,只渲染實際變化的子組件,?從而高效地更新瀏覽器顯示的DOM。
生命周期方法
生命周期方法是指在組件的生命周期內,允許在設定的點執行代碼的hooks處理函數。
l??shouldComponentUpdate允許開發者在不需要渲染的情況下,通過返回false來防止不必要的重新渲染組件。
l??componentDidMount是在組件?"掛載?"后調用的(組件已經在用戶界面中創建了,通常是通過將其與DOM節點關聯起來)。這通常用于通過API從遠程數據源觸發數據加載。
l??componentWillUnmount是在組件被拆解或?"解掛?"之前立即調用的。這通常用于清除組件的資源依賴關系,這些依賴關系不會隨著組件的卸載而簡單地被移除(例如,移除任何與組件相關的setInterval()實例,或者因為組件的存在而在?"文檔?"上設置的?"eventListener")。
l??render是最重要的生命周期方法,也是任何組件中唯一必須存在的方法。它通常在每次更新組件的狀態時都會被調用。
JSX
JSX,即JavaScript XML,是對JavaScript語言語法的擴展。JSX在外觀上類似于HTML,它提供了一種開發者熟悉的語法結構化組件渲染的方法。React組件通常是使用JSX編寫的,盡管不一定非要使用JSX(組件也可以用純JavaScript編寫)。JSX類似于Facebook為PHP創建的另一種名為XHP的擴展語法。
JSX代碼的一個例子:
class?App?extends?React.Component?{
render()?{
return?(
Header
Content
Footer
);
}
}
嵌套元素
同一層次上的多個元素需要被包裹在一個容器元素中,如上圖中的
屬性
JSX提供了一系列的元素屬性,旨在對應HTML提供的屬性。這些自定義的屬性也可以傳遞給組件,所有的屬性都會被組件作為props接收。
JavaScript表達式
JavaScript表達式(但不是語句)可以在JSX內部通過大括號{}使用。
{10+1}
上面代碼的顯示結果是:
11
條件語句
If-else語句不能在JSX中使用,但可以使用條件表達式來代替。下面的例子當i為1時將?{ i === 1 ? 'true' : 'false' }?呈現為字符串?'true'。
class?App?extends?React.Component?{
render()?{
const?i?=?1;
return?(
{?i?===?1???'true'?:?'false'?}
);
}
}
結果會是:
true
函數和JSX可以用于條件表達式中:
class?App?extends?React.Component?{
render()?{
const?sections?=?[1,?2,?3];
return?(
{sections.length?>?0?&&?sections.map(n?=>?(
/*?'key'必須唯一?*/
))}
);
}
}
結果會是:
用JSX編寫的代碼需要被Babel等工具進行轉換以后才能被Web瀏覽器所理解,這種處理一般是在軟件構建過程中進行的,然后再部署構建后的應用程序。
超越HTML的架構
React的基本架構不僅僅適用于在瀏覽器中渲染HTML。例如,Facebook有動態圖表,可以渲染到
React Hooks
Hooks是讓開發者從函數組件中?"鉤入"React狀態和生命周期特性的函數。它們使代碼具有更強的可讀性且更易理解。Hooks并不在類組件內工作,它的終極目標是在React中消除類組件的存在。
React提供了一些內置的Hooks,如useState、useContext、useReducer和useEffect等。它們都在Hooks API參考書中做了說明。使用最多的是useState和useEffect,分別在React組件中控制狀態和檢測狀態變化。
Hooks規則
Hooks也有一些規則,在使用Hooks之前必須遵循這些規則:
l??鉤子只能在頂層調用(不能在循環或if語句中調用)。
l??鉤子只能在React函數組件中調用,不能在普通函數或類組件中調用。
定制Hooks
構建自己的Hooks,也就是所謂的自定義Hooks,可以讓你把組件邏輯提取到可重用的函數中。自定義鉤子是一個名稱以?"use "開頭的JavaScript函數,它可以調用其他的鉤子。鉤子的規則也適用于它們。
常用術語
React并沒有試圖提供一個完整的?"應用程序庫"。它是專門為構建用戶界面而設計的,因此并不包括許多一些開發者認為構建應用程序所需的工具。這使得開發者可以選擇任何一個庫來完成諸如執行網絡訪問或本地數據存儲等任務。這種情況也就決定了React技術在創建網頁應用時標準無法統一。
Flux架構的使用
為了支持React的單向數據流的概念(與AngularJS/Angular的雙向數據流形成對比),Flux架構是流行的模型-視圖-控制器(MVC)架構的具有代表性的替代方案。Flux的特點是,數據動作通過中央調度器發送到一個存儲倉庫,而對存儲倉庫數據的變化會被傳送回視圖。當與React一起使用時,這種傳送是通過組件屬性完成的。
Flux可以被認為是觀察者模式的一個變種。
Flux架構下的React組件不應該直接修改傳遞給它的任何props,而是應該傳遞回調函數,這些回調函數可以創建由調度器發送的數據動作來修改存儲倉庫。數據動作是一個對象,其職責是描述已經發生的事情:例如,一個數據動作描述的是一個用戶?"follow"另一個用戶。它可能包含如下數據:
用戶ID,
目標用戶ID,
以及USER_FOLLOWED_ANOTHER_USER枚舉類型。
存儲倉庫,是一個數據模型,可以根據從調度器接收到的數據動作來改變自己。
這種模式有時被表述為?"屬性向下流動,數據動作向上流動"。自Flux誕生以來,Flux的許多實現被創造出來,其中最著名的是Redux,它的特點是單一的存儲倉庫,通常被稱為單一的數據真相源。
歷史
React是由Facebook的軟件工程師Jordan Walke創建的,受PHP的HTML組件庫XHP的啟發,發布了React的早期原型,名為?"FaxJS",。它于2011年首次部署在Facebook的News Feed上,后來于2012年部署在Instagram上。2013年5月在美國JSConf大會上開源。
React Native是2015年2月在Facebook的React Conf上宣布的,2015年3月開源的React Native,實現了原生的Android、iOS和UWP開發。
2017年4月18日,Facebook宣布了React Fiber,這是React庫的一個新的核心算法,用于構建用戶界面,React Fiber將成為React庫未來任何改進和功能開發的基礎。
2017年9月26日,React 16.0正式對外發布。
2019年2月16日,React 16.8正式對外發布,該版本引入了React Hooks。
常用命令
創建工程:
npx create-react-app my-app
開發環境運行:
npm start
生產環境打包:
npm run build
【官方網站】
http://reactjs.org/
【最新版本】
16.13.1于2020年3月19日
【授權】
MIT License
【Angular】
Angular(通常被稱為?"Angular 2+"或?"Angular v2及以上版本")是一個基于TypeScript的開源Web應用框架,由Google的Angular團隊和由個人以及企業組成的社區領導。?Angular是由構建AngularJS的同一個團隊從零開始重寫的。
Angular和AngularJS的區別
l??Angular沒有?"Scope"或控制器的概念,相反,它使用組件的層次結構作為其主要的架構特征。
l??Angular有不同的表達式語法,重點是"[]"用于屬性綁定,"() "用于事件綁定
l??模塊化?-?許多核心功能已轉移到模塊上
l??Angular推薦使用微軟的TypeScript語言,它引入了以下特性。
n??靜態鍵入,包括Generics
n??注解
l??TypeScript是ECMAScript 6 (ES6)的超集,向后兼容ECMAScript 5(即:JavaScript)。
l??動態加載
l??異步模板編譯
l??由RxJS提供的迭代回調。RxJS限制了狀態的可見性和調試,但這些問題可以通過像ngReact或ngrx這樣的反應式附加組件來解決。
l??支持Angular Universal,可以在服務器上運行Angular應用程序。
歷史
命名
最初,AngularJS的重寫被稱為?"Angular 2",但這導致了開發人員的迷糊。為了澄清,團隊宣布,每個框架使用不同的術語,其中?"AngularJS "指的是1.X版本,?"Angular "?指的是2及以上版本。
版本2
Angular 2.0在2014年10月22-23日的ng-Europe大會上宣布。2.0版本的劇烈變化在開發者中引起了相當大的爭議。
2015年4月30日,Angular開發者宣布Angular 2從Alpha轉為開發者預覽版,2015年12月Angular 2轉為Beta版,2016年5月發布了第一個發布候選版本,2016年9月14日發布了最終版本。
版本4
2016年12月13日Angular 4發布,跳過了3,避免了因路由器包的版本錯位導致的混亂,當時已經發布的版本為v3.3.0。最終版本于2017年3月23日發布,Angular 4向后兼容Angular 2。
Angular 4.3版本是一個小版本,它是4.x.x版本的替換版本。
4.3版本的功能
l??介紹了HttpClient,一個更小、更容易使用、更強大的HTTP請求庫。
l??為守護者和解析器提供了新的路由器生命周期事件。四個新事件。GuardsCheckStart、GuardsCheckEnd、ResolveStart、ResolveEnd加入了現有的NavigationStart等生命周期事件集。
l??有條件地禁用動畫。
版本5
Angular 5于2017年11月1日發布,Angular 5的主要改進包括支持漸進式Web應用、構建優化器以及與Material Design相關的改進。
版本6
Angular 6于2018年5月4日發布。這個版本,關注的重點不在于底層框架,更多的是工具鏈,以及讓Angular在未來的更新和升級更加容易,比如:ngupdate、ng add、Angular元素、Angular Material+CDK組件、Angular Material入門組件、CLI工作區、庫支持、樹形搖動提供者、動畫性能提升、RxJS v6。
版本7
Angular 7已于2018年10月18日發布。更新內容涉及到應用性能、Angular Material & CDK、虛擬滾動、Selects的可訪問性改進、現在支持自定義元素使用Web標準的內容投影,以及關于Typescript 3.1、RxJS 6.3、Node 10(仍支持Node 8)的依賴性更新。
版本8
l??生成的代碼,在運行時更容易閱讀和調試。
l??更快的重建時間
l??減少有效載荷
l??改進了模板類型檢查
l??向后兼容
版本9
Angular 9已于2020年2月6日發布。第9版在默認情況下使用Ivy編譯器。Angular可以與TypeScript 3.6和3.7兼容。除了數百個bug修復之外,Ivy編譯器和運行時還提供了許多優勢:
l??更小的軟件包
l??更快的測試
l??更好的調試
l??改進的CSS類和樣式綁定
l??改進的類型檢查
l??改善了構建錯誤
l??改善了構建時間,默認開啟AOT功能
l??提高國際化功能
特點
組件化
一個組件例子
Products
{{?product.name?}}
export?class?ProductListComponent?{
products?=?products;
}
路由
@NgModule({
imports:?[
BrowserModule,
ReactiveFormsModule,
RouterModule.forRoot([
{?path:?'',?component:?ProductListComponent?},
{?path:?'products/:productId',?component:?ProductDetailsComponent?},
])
],
數據管理
定義服務類
export?class?CartService?{
items?=?[];
constructor(
private?http:?HttpClient
)?{}
addToCart(product)?{
this.items.push(product);
}
getItems()?{
return?this.items;
}
clearCart()?{
this.items?=?[];
return?this.items;
}
getShippingPrices()?{
return?this.http.get('/assets/shipping.json');
}
}
調用服務類
export?class?ShippingComponent?implements?OnInit?{
shippingCosts;
constructor(
private?cartService:?CartService
)?{
}
ngOnInit()?{
this.shippingCosts?=?this.cartService.getShippingPrices();
}
}
常用命令
從終端上,全局安裝Angular CLI:
npm install -g @angular/cli
使用?ng new?命令創建一個新的?Angular CLI?工作區:
ng new my-project-name
開發環境運行:
ng serve
生產環境打包:
ng build --prod
【官方網站】
https://angular.io/
【最新版本】
9.1.2于2020年4月15日
【授權】
MIT License
【Vue】
Vue.js(通常被稱為Vue;發音為/vju?/,類似于?"view")是一個開源的Model-view-viewmodel JavaScript框架,用于構建用戶界面和單頁面應用程序。它由Evan You創建,由他和來自Netlify和Netguru等多家公司的核心成員維護。
概述
Vue.js的特點是,它采用了一個漸進式的架構,專注于聲明式渲染和組件合成。復雜應用所需的高級功能,如路由、狀態管理和構建工具等,都是通過官方維護的支持庫和包提供的,其中Nuxt.js是最受歡迎的解決方案之一。
Vue.js可以讓你用稱為指令(directives)的HTML屬性來擴展HTML。
歷史
Vue是由Evan You創建的。在Google工作期間,他使用AngularJS技術參與了多個項目的開發的,之后創建了Vue。他后來總結了自己的思考過程。"我想,如果我可以把AngularJS真正優秀的部分提取出來,然后構建一些輕量級的東西,會怎么樣呢?"?項目的第一個版本源碼提交日期是2013年7月,Vue在2014年2月首次發布。
特點
組件化
Vue?組件擴展了基本的?HTML?元素來封裝可重用的代碼。從高層次的角度看,組件是Vue編譯器附加行為的自定義元素。在Vue中,組件本質上就是一個帶有預設選項的Vue實例。下面的代碼片段包含了一個Vue組件的例子。該組件顯示了一個按鈕,并打印出按鈕被點擊的次數。
Vue.component('button-clicked',?{
props:?[?"initialCount"?],
data:?()?=>?({
count:?0,
}),
template:?``,
computed:?{
countTimesTwo()?{
return?this.count?*?2;
}
},
watch:?{
count(newValue,?oldValue)?{
console.log(`The?value?of?count?is?changed?from?${oldValue}?to?${newValue}.`);
}
},
methods:?{
onClick()?{
this.count?+=?1;
}
},
mounted()?{
this.count?=?this.initialCount;
}
});
new?Vue({
el:?'#tuto',
});
模板
Vue使用基于HTML的模板語法,允許將渲染的DOM綁定到Vue實例的底層數據。所有?Vue?模板都是有效的?HTML,可以被符合規范的瀏覽器和?HTML?解析器解析。Vue?將模板編譯成虛擬?DOM?渲染函數。虛擬文檔對象模型(或?"DOM")允許Vue在更新瀏覽器之前在其內存中渲染組件。結合反應式系統,Vue能夠計算出需要重新渲染的組件的最小數量,并在App狀態發生變化時,啟動最小量的DOM操作。
Vue用戶可以使用模板語法,也可以選擇使用JSX直接編寫渲染函數,渲染函數允許從軟件組件中構建應用程序。
反應式系統
Vue的特點是采用了反應式系統,它使用純JavaScript對象和優化的重渲染。每個組件在渲染過程中都會跟蹤其反應式的依賴關系,因此系統可以精確地知道什么時候重新渲染,以及哪些組件需要重新渲染。
變換效果
當從DOM中插入、更新或刪除項目時,Vue提供了多種方法來部署變換效果。這包括了以下工具:
l??自動應用CSS變換和動畫的類
l??集成第三方CSS動畫庫,如Animate.css等。
l??在變換hooks期間,使用JavaScript直接操作DOM。
l??集成第三方JavaScript動畫庫,如Velocity.js等。
當在變換組件中的元素被插入或移除時,會出現這樣的情況:
l??Vue會自動檢測到目標元素是否應用了CSS變換或動畫。如果有,CSS變換類將在適當的時間添加/刪除。
l??如果變換組件提供了JavaScript hooks,這些hooks將在適當的時間被調用。
l??如果沒有檢測到CSS變換/動畫,并且沒有提供JavaScript hooks,那么插入和/或移除的DOM操作將在下一幀中立即執行。
路由
單頁面應用程序(SPA)的一個傳統缺點是無法分享到特定網頁中的確切?"子?"頁面的鏈接。由于SPA只向用戶提供一個基于URL的服務器響應(它通常服務于index.html或index.vue),因此通常情況下,將某些屏幕作為書簽或分享到特定部分的鏈接是很困難的,甚至是不可能的。為了解決這個問題,許多客戶端路由器用?"hashbang"(#!)來劃分動態URL,例如page.com/#!/。然而,在HTML5中,大多數現代瀏覽器都支持不使用hashbang的路由。
Vue提供了一個界面,可以根據當前的URL路徑來改變頁面上顯示的內容?–?可以有多種方式(無論是通過電子郵件鏈接、刷新還是頁面內鏈接)。此外,當某些瀏覽器事件(如點擊)發生在按鈕或鏈接上時,使用前端路由器可以有意識地轉換瀏覽器路徑。Vue本身并沒有自帶前端路由。但開源的?"vue-router "包提供了一個API來更新應用程序的URL,支持返回按鈕(導航歷史記錄),并支持電子郵件密碼重置或電子郵件驗證鏈接的認證URL參數。它支持將嵌套路由映射到嵌套組件,并提供精細化的過渡控制。添加了vue-router后,組件只需映射到它們所屬的路由,父/根路由必須指明子路由的渲染位置。
...
...
const?User?=?{
template:?'
}
const?router?=?new?VueRouter({
routes:?[
{?path:?'/user/:id',?component:?User?}
]
})
...
上面的代碼:
l??在websitename.com/user/
l??這將在(const User...)中定義的User組件中呈現。
l??允許用戶組件使用$route對象的params鍵輸入用戶的特定ID:$route.params.id。
l??這個模板(根據傳遞到路由器中的參數變化)將被渲染到DOM的div#app里面的
l??最后生成的HTML將是:websitename.com/user/1:
生態系統
核心庫自帶的工具和庫都是由核心團隊和貢獻者開發的。
官方工具
l??Devtools -?用于調試Vue.js應用程序的瀏覽器devtools擴展。
l??Vue CLI -?用于快速開發Vue.js的標準工具書
l??Vue Loader -?一個webpack加載器,允許以單文件組件(SFCs)的格式編寫Vue組件。
官方程序庫
l??Vue Router - Vue.js的官方路由器
l??Vuex –?基于?Flux模式的?Vue.js?的集中式狀態管理。
l??Vue Server Renderer -?用于?Vue.js?的服務器端渲染。
常用命令
安裝工具
npm install -g @vue/cli
創建工程:
vue create my-project
開發環境運行:
npm run serve
生產環境打包:
npm run build
【官方網站】
https://vuejs.org/
【最新版本】
2.6.1于2019年12月13日
【授權】
MIT License
【小結】
本文對于當前頂級的前端技術做了較為詳盡的探索,前端技術一個大的方向是單頁應用?(SPA,Single Page Application),我們在選取針對本業務的前端技術時需要結合如下幾個方面來考慮:
1.?????成員當前技能,這是一個很現實的問題,大多數程序員會選擇自己比較熟悉的技術。這里要思考一下,目前自己熟悉的技術是不是最優選項?
2.?????可利用的學習時間,如果發現要使用的技術需要一些時間學習,這個時間的開銷到底會不會與開發進度有沖突?
3.?????能否保證項目的復雜度最低,這個是比較關鍵的因素。先進技術之所以先進就是因為可以讓開發者把時間和精力放在真正的業務開發上面來,如果要使用的技術需要進行很多與業務不相關的配置,就需要問一個問題,有沒有更好的辦法?
最后,希望本文對現有或者以后的業務開發有指導或者借鑒作用。
web前端
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。