Vue.js : 是一套構建用戶界面的漸進式框架。
一、什么是框架?
在最初前端開發中,為了完成某個任務,我們首先利用js從html文件中獲取dom元素,隨后添加事件,最后進行一系列的js編程操作,這種開發方式暫且稱為“don流”,在現實開發中需求變化,復雜的業務邏輯和巨大的代碼量是“dom流”無法承受的,
對應以上問題,衍變出了把js代碼劃分為三個板塊:數據,視圖,邏輯控制,數據版塊只含有數據內容,視圖板塊只負責更改樣式,邏輯控制負責聯系視圖板塊和數據版塊和相應的邏輯。這樣代碼結構變得清晰易懂,因需求而改動代碼程度變小。
其實這種開發方式,就是我們常說的MV模式,而MVC、MVVM、 MVP[2]等都是MV的衍生物
而這種MV*的代碼組織方式,漸漸的就演變成了所謂的框架。
Vue的核心定位并不是一個框架,設計上也沒有完全遵循MVVM模式,可以看到在圖中只有State和View兩部分, Vue的核心功能強調的是狀態到界面的映射,對于代碼的結構組織并不重視, 所以單純只使用其核心功能時,它并不是一個框架,而更像一個視圖模板引擎,這也是為什么Vue開發者把其命名成讀音類似于view的原因。
二、對漸進式的理解:
如下圖所示,這里包含了Vue的所有部件,在聲明式渲染(視圖模板引擎)的基礎上,我們可以通過添加組件系統、客戶端路由、大規模狀態管理來構建一個完整的框架。更重要的是,這些功能相互獨立,你可以在核心功能的基礎上任意選用其他的部件,不一定要全部整合在一起。可以看到,所說的“漸進式”,其實就是Vue的使用方式,同時也體現了Vue的設計的理念
以上參考 (http://blog.csdn.net/crazy_banana/article/details/71079925)
Vue.js是一個提供MVVM數據雙向綁定的庫,專注于UI層面,核心思想是:數據驅動、組件系統。
三、核心內容
【1】、Vue渲染邏輯
===============Render函數===============
$mount方法就是整個渲染過程的起始點
在渲染過程中,提供了三種渲染模式,自定義Render函數、template、el均可以渲染頁面,也就是對應我們使用Vue時,三種寫法:
2、3這兩種都屬于聲明式渲染
1. 自定義Render函數
1.Vue.component('anchored-heading', {
2. render: function (createElement) {
3. return createElement(
4. 'h' + this.level, // tag name 標簽名稱
5. this.$slots.default // 子組件中的陣列
6. )
7. },
8. props: {
9. level: {
10. type: Number,
11. required: true
12. }
13. }
14.})
2. template寫法
1.var vm = new Vue({
2. data: {
3. // 以一個空值聲明 `msg`
4. msg: ''
5. },
6. template: '<div>{{msg}}</div>'
7.})
3. el寫法(這個就是入門時最基本的寫法)
1.var app = new Vue({
2. el: '#app',
3. data: {
4. message: 'Hello Vue!'
5. }
6.})
這三種渲染模式最終都是要得到Render函數。只不過用戶自定義的Render函數省去了程序分析的過程,等同于處理過的Render函數,而普通的template或者el只是字符串,需要解析成AST,再將AST轉化為Render函數。
===============虛擬DOM&patch方法===============
Virtual DOM有多種實現方式,但基本思路都是一樣的,分為兩步:
1.Render函數生成Virtual DOM
VNode對象是什么?
VNode就是Vue.js 2.0中的Virtual DOM,在Vue.js 2.0中,相較Vue.js 1.0引入了Virtual DOM的概念
在Vue.js 2.0中Javascript模擬DOM模型樹就是VNode,Render函數執行后都會返回VNode對象,為下一步操作做準備。
2.Virtual DOM通過DOM Diff算法查找差異,將差異轉為真正DOM節點
Render函數執行生成了VNode,而VNode只是Virtual DOM,我們還需要通過DOM Diff之后,來生成真正的DOM節點。在Vue.js 2.0中,是通過/src/core/vdom/patch.js中的patch(oldVnode, vnode ,hydrating)方法來完成的。
其主要邏輯為當VNode為真實元素或舊的VNode和新的VNode完全相同時,直接調用createElm方法生成真實的DOM樹,當VNode新舊存在差異時,則調用patchVnode方法,通過比較新舊VNode節點,根據不同的狀態對DOM做合理的添加、刪除、修改DOM(這里的Diff算法有興趣的讀者可以自行閱讀patchVnode方法,鑒于篇幅不再贅述),再調用createElm生成真實的DOM樹。
===============Watcher & 數據驅動 & 依賴追蹤===============
2、什么是數據驅動
數據驅動是vuejs最大的特點。在vuejs中,所謂的數據驅動就是當數據發生變化的時候,用戶界面發生相應的變化,開發者不需要手動的去修改dom。
vuejs是如何實現這種數據驅動的呢?
Vuejs的數據驅動是通過MVVM這種框架來實現的。MVVM框架主要包含3個部分:model、view和 viewmodel。
Model:指的是數據部分,對應到前端就是javascript對象
View:指的是視圖部分,對應前端就是dom
Viewmodel:就是連接視圖與數據的中間件
數據(Model)和視圖(View)是不能直接通訊的,而是需要通過ViewModel來實現雙方的通訊。當數據變化的時候,viewModel能夠監聽到這種變化,并及時的通知view做出修改。同樣的,當頁面有事件觸發時,viewMOdel也能夠監聽到事件,并通知model進行響應。Viewmodel就相當于一個觀察者,監控著雙方的動作,并及時通知對方進行相應的操作。
vuejs是通過在實現一個觀察者來實現的數據驅動。
如何實現數據驅動的?
首先,vuejs在實例化的過程中,會對遍歷傳給實例化對象選項中的data 選項,遍歷其所有屬性并使用 Object.defineProperty 把這些屬性全部轉為 getter/setter。
同時每一個實例對象都有一個watcher實例對象,他會在模板編譯的過程中,用getter去訪問data的屬性,watcher此時就會把用到的data屬性記為依賴,這樣就建立了視圖與數據之間的聯系。當之后我們渲染視圖的數據依賴發生改變(即數據的setter被調用)的時候,watcher會對比前后兩個的數值是否發生變化,然后確定是否通知視圖進行重新渲染。
這樣就實現了所謂的數據對于視圖的驅動。
3、vue響應式原理---依賴追蹤
Vue的依賴追蹤通過ES5的 Object.defineProperty 方法實現。
比如,我們給它一個原生對象,Vue會遍歷這個數據對象的屬性,然后進行屬性轉換。每一個屬性會被轉換為一個 getter 和一個 setter。同時每個組件會有一個對應的 watcher 對象,這個對象的職責就是在當前組件被渲染的時候,記錄數據上面的哪些屬性被用到了。
例如,在渲染函數里面用到A.B的時候,這個就會觸發對應的 getter。整個渲染流程具體要點如下:
當某個數據屬性被用到時,觸發 getter,這個屬性就會被作為依賴被 watcher 記錄下來。
整個函數被渲染完的時候,每一個被用到的數據屬性都會被記錄。
相應的數據變動時,例如給它一個新的值,就會觸發 setter,通知數據對象對應數據有變化。
此時會通知對應的組件,其數據依賴有所改動,需要重新渲染。
對應的組件再次調動渲染函數,生成 Virtual DOM,實現 DOM 更新。
在Vue里面由于依賴追蹤系統的存在,當任意數據變動的時,Vue的每一個組件都精確地知道自己是否需要重繪,所以并不需要手動優化。用Vue渲染這些組件的時候,數據變了,對應的組件基本上去除了手動優化的必要性。
核心關鍵的幾步流程還是非常清晰的:
1、new Vue,執行初始化
2、掛載$mount方法,通過自定義Render方法、template、el等生成Render函數
3、通過Watcher監聽數據的變化
4、當數據發生變化時,Render函數執行生成VNode對象
5、通過patch方法,對比新舊VNode對象,通過DOM Diff算法,添加、修改、刪除真正的DOM元素
至此,整個new Vue的渲染過程完畢。
render流程:
1、創建虛擬DOM
2、真實DOM 連接 虛擬DOM
3、視圖更新
4、計算 [ 新虛擬DOM ] 和 [ 舊虛擬DOM ] 的差異 ( diff )
5、根據計算的 差異, 更新真實DOM ( patch )
這里牽涉到兩個詞語 diff 和 patch,稍后再解釋,這里簡單理解為 [計算差異]和[應用差異]。
【2】、組件系統
核心思想都是一樣,把UI結構映射到恰當的組件樹
在Vue中,父子組件之間的通信是通過 props 傳遞。從父向子單向傳遞;而如果子組件想要在父組件作用里面產生副作用,就需要去派發事件。這樣就形成一個基本的父子通信模式,在涉及大規模狀態管理的時候會有額外的方案,這個后面會提到。
組件+構建工具==> 單文件組件概念
在同一個Vue文件里,可以同時寫 template, script 和 style,三個東西放在一個里面。這樣的好處是有了一個構建的機會,可以對這些單文件組件做更多的分析處,在每一個語言塊里可以單獨使用不同的處理器
以上參考
http://blog.csdn.net/generon/article/details/72482844
https://www.cnblogs.com/caizhenbo/p/6418284.html
https://www.tuicool.com/articles/6nEjAjb
https://cn.vuejs.org/v2/guide/reactivity.html