Vue爲MVVM框架,當數據模型data變化時,頁面視圖會獲得響應更新,其原理對data的getter/setter方法進行攔截(Object.defineProperty或者Proxy),利用發佈訂閱的設計模式,在getter方法中進行訂閱,在setter方法中發佈通知,讓全部訂閱者完成響應。vue
在響應式系統中,Vue會爲數據模型data的每個屬性新建一個訂閱中心做爲發佈者,而監聽器watch、計算屬性computed、視圖渲染template/render三個角色同時做爲訂閱者,對於監聽器watch,會直接訂閱觀察監聽的屬性,對於計算屬性computed和視圖渲染template/render,若是內部執行獲取了data的某個屬性,就會執行該屬性的getter方法,而後自動完成對該屬性的訂閱,當屬性被修改時,就會執行該屬性的setter方法,從而完成該屬性的發佈通知,通知全部訂閱者進行更新。node
計算屬性computed和監聽器watch均可以觀察屬性的變化從而作出響應,不一樣的是:react
計算屬性computed更可能是做爲緩存功能的觀察者,它能夠將一個或者多個data的屬性進行復雜的計算生成一個新的值,提供給渲染函數使用,當依賴的屬性變化時,computed不會當即從新計算生成新的值,而是先標記爲髒數據,當下次computed被獲取時候,纔會進行從新計算並返回。webpack
而監聽器watch並不具有緩存性,監聽器watch提供一個監聽函數,當監聽的屬性發生變化時,會當即執行該函數。git
beforeCreate
:是new Vue()以後觸發的第一個鉤子,在當前階段data、methods、computed以及watch上的數據和方法都不能被訪問。github
created
:在實例建立完成後發生,當前階段已經完成了數據觀測,也就是可使用數據,更改數據,在這裏更改數據不會觸發updated函數。能夠作一些初始數據的獲取,在當前階段沒法與Dom進行交互,若是非要想,能夠經過vm.$nextTick來訪問Dom。web
beforeMount
:發生在掛載以前,在這以前template模板已導入渲染函數編譯。而當前階段虛擬Dom已經建立完成,即將開始渲染。在此時也能夠對數據進行更改,不會觸發updated。正則表達式
mounted
:在掛載完成後發生,在當前階段,真實的Dom掛載完畢,數據完成雙向綁定,能夠訪問到Dom節點,使用$refs屬性對Dom進行操做。算法
beforeUpdate
:發生在更新以前,也就是響應式數據發生更新,虛擬dom從新渲染以前被觸發,你能夠在當前階段進行更改數據,不會形成重渲染。數據庫
updated
:發生在更新完成以後,當前階段組件Dom已完成更新。要注意的是避免在此期間更改數據,由於這可能會致使無限循環的更新。
beforeDestroy
:發生在實例銷燬以前,在當前階段實例徹底能夠被使用,咱們能夠在這時進行善後收尾工做,好比清除計時器。
destroyed
:發生在實例銷燬以後,這個時候只剩下了dom空殼。組件已被拆解,數據綁定被卸除,監聽被移出,子實例也通通被銷燬。
一個組件可能在不少地方使用,也就是會建立不少個實例,若是data是一個對象的話,對象是引用類型,一個實例修改了data會影響到其餘實例,因此data必須使用函數,爲每個實例建立一個屬於本身的data,使其同一個組件的不一樣實例互不影響。
父組件 -> 子組件:prop
子組件 -> 父組件:$on/$emit
獲取組件實例:使用$parent/$children
,$refs.xxx
,獲取到實例後直接獲取屬性數據或調用組件方法
Event Bus:每個Vue實例都是一個Event Bus,都支持$on/$emit
,能夠爲兄弟組件的實例之間new一個Vue實例,做爲Event Bus進行通訊。
Vuex:將狀態和方法提取到Vuex,完成共享
使用provide/inject
Event Bus:同兄弟組件Event Bus通訊
Vuex:將狀態和方法提取到Vuex,完成共享
每個Vue實例都是一個Event Bus,當子組件被建立的時候,父組件將事件傳遞給子組件,子組件初始化的時候是有$on
方法將事件註冊到內部,在須要的時候使用$emit
觸發函數,而對於原生native事件,使用addEventListener綁定到真實的DOM元素上。
slot又名插槽,是Vue的內容分發機制,組件內部的模板引擎使用slot元素做爲承載分發內容的出口。插槽slot是子組件的一個模板標籤元素,而這一個標籤元素是否顯示,以及怎麼顯示是由父組件決定的。
slot又分三類,默認插槽,具名插槽和做用域插槽。
實現原理:當子組件vm實例化時,獲取到父組件傳入的slot標籤的內容,存放在vm.$slot
中,默認插槽爲vm.$slot.default
,具名插槽爲vm.$slot.xxx
,xxx 爲插槽名,當組件執行渲染函數時候,遇到slot標籤,使用$slot
中的內容進行替換,此時能夠爲插槽傳遞數據,若存在數據,則可稱該插槽爲做用域插槽。
vue中的模板template沒法被瀏覽器解析並渲染,由於這不屬於瀏覽器的標準,不是正確的HTML語法,全部須要將template轉化成一個JavaScript函數,這樣瀏覽器就能夠執行這一個函數並渲染出對應的HTML元素,就可讓視圖跑起來了,這一個轉化的過程,就成爲模板編譯。
模板編譯又分三個階段,解析parse,優化optimize,生成generate,最終生成可執行函數render。
對於 Vue 組件來講,模板編譯只會在組件實例化的時候編譯一次,生成渲染函數以後在也不會進行編譯。所以,編譯對組件的 runtime 是一種性能損耗。
而模板編譯的目的僅僅是將template轉化爲render function
,這個過程,正好能夠在項目構建的過程當中完成,這樣可讓實際組件在 runtime 時直接跳過模板渲染,進而提高性能,這個在項目構建的編譯template的過程,就是預編譯。
對於 runtime 來講,只須要保證組件存在 render 函數便可,而咱們有了預編譯以後,咱們只須要保證構建過程當中生成 render 函數就能夠。
在 webpack 中,咱們使用vue-loader
編譯.vue文件,內部依賴的vue-template-compiler
模塊,在 webpack 構建過程當中,將template預編譯成 render 函數。
與 react 相似,在添加了jsx的語法糖解析器babel-plugin-transform-vue-jsx
以後,就能夠直接手寫render函數。
因此,template和jsx的都是render的一種表現形式,不一樣的是:
JSX相對於template而言,具備更高的靈活性,在複雜的組件中,更具備優點,而 template 雖然顯得有些呆滯。可是 template 在代碼結構上更符合視圖與邏輯分離的習慣,更簡單、更直觀、更好維護。
Virtual DOM 是 DOM 節點在 JavaScript 中的一種抽象數據結構,之因此須要虛擬DOM,是由於瀏覽器中操做DOM的代價比較昂貴,頻繁操做DOM會產生性能問題。虛擬DOM的做用是在每一次響應式數據發生變化引發頁面重渲染時,Vue對比更新先後的虛擬DOM,匹配找出儘量少的須要更新的真實DOM,從而達到提高性能的目的。
在新老虛擬DOM對比時
在diff中,只對同層的子節點進行比較,放棄跨級的節點比較,使得時間複雜從O(n^3)
下降值O(n)
,也就是說,只有當新舊children都爲多個子節點時才須要用核心的Diff算法進行同層級比較。
在對節點進行diff的過程當中,判斷是否爲相同節點的一個很重要的條件是key是否相等,若是是相同節點,則會盡量的複用原有的DOM節點。因此key屬性是提供給框架在diff的時候使用的,而非開發者。
Vue2.0中,隨着功能的增長,組件變得愈來愈複雜,愈來愈難維護,而難以維護的根本緣由是Vue的API設計迫使開發者使用watch,computed,methods選項組織代碼,而不是實際的業務邏輯。
另外Vue2.0缺乏一種較爲簡潔的低成本的機制來完成邏輯複用,雖然能夠minxis完成邏輯複用,可是當mixin變多的時候,會使得難以找到對應的data、computed或者method來源於哪一個mixin,使得類型推斷難以進行。
因此Composition API的出現,主要是也是爲了解決Option API帶來的問題,第一個是代碼組織問題,Compostion API可讓開發者根據業務邏輯組織本身的代碼,讓代碼具有更好的可讀性和可擴展性,也就是說當下一個開發者接觸這一段不是他本身寫的代碼時,他能夠更好的利用代碼的組織反推出實際的業務邏輯,或者根據業務邏輯更好的理解代碼。
第二個是實現代碼的邏輯提取與複用,固然mixin也能夠實現邏輯提取與複用,可是像前面所說的,多個mixin做用在同一個組件時,很難看出property是來源於哪一個mixin,來源不清楚,另外,多個mixin的property存在變量命名衝突的風險。而Composition API恰好解決了這兩個問題。
從React Hook的實現角度看,React Hook是根據useState調用的順序來肯定下一次重渲染時的state是來源於哪一個useState,因此出現瞭如下限制
而Composition API是基於Vue的響應式系統實現的,與React Hook的相比
雖然Compositon API看起來比React Hook好用,可是其設計思想也是借鑑React Hook的。
在客戶端請求服務器的時候,服務器到數據庫中獲取到相關的數據,而且在服務器內部將Vue組件渲染成HTML,而且將數據、HTML一併返回給客戶端,這個在服務器將數據和組件轉化爲HTML的過程,叫作服務端渲染SSR。
而當客戶端拿到服務器渲染的HTML和數據以後,因爲數據已經有了,客戶端不須要再一次請求數據,而只須要將數據同步到組件或者Vuex內部便可。除了數據意外,HTML也結構已經有了,客戶端在渲染組件的時候,也只須要將HTML的DOM節點映射到Virtual DOM便可,不須要從新建立DOM節點,這個將數據和HTML同步的過程,又叫作客戶端激活。
使用SSR的好處:
更多詳情查看 完全理解服務端渲染-SSR原理 https://github.com/yacan8/blo...