你應該要知道的Vue.js

該篇文章主要對Vue中應該要掌握的知識點的一些整理。只是一個引子,並沒有過多的深入,但是希望能根據這篇文章從各個點對Vue有一個更好的瞭解,對自己有一個更好的定位。只會用API的前端不是好的程序員。

組件data爲什麼必須是函數?

因爲組件可能被多處使用,但它們的data是私有的,所以每個組件都要return一個新的data對象,如果共享data,修改其中一個會影響其他組件

組件通信

  • 父子組件通信:$on$emit
  • 非父子組件的通信: event bus
  • 複雜情況: vuex

怎麼動態添加組件

場景:在vue中,點擊button,隨機生成a、b、c組件中的一個

  • is
  • render

思路:設定一個components數組,button點擊一次,push一個組件名,v-for遍歷components,並用isrender動態生成

vue-loader是什麼?

vue-loader 是一個 webpack 的 loader,可以將單文件組件轉換爲 JavaScript 模塊

引用文檔的說法:

  • 默認支持 ES2015
  • 允許對 Vue 組件的組成部分使用其它 webpack loader,比如對 <style> 使用 Sass 和對 <template> 使用 Jade
  • .vue 文件中允許自定義節點,然後使用自定義的 loader 進行處理;
  • <style><template> 中的靜態資源當作模塊來對待,並使用 webpack loader 進行處理;
  • 對每個組件模擬出 CSS 作用域;
  • 支持開發期組件的熱重載。

實現 Vue SSR基本原理

主要通過vue-server-renderer將Vue組件輸出成HTML,過程:

  1. 客戶端 entry-client 主要作用掛載到 DOM 上,服務端 entry-server 除了創建和返回實例,還進行路由匹配與數據預獲取
  2. webpack打包客戶端爲client-bundle,打包服務端爲server-bundle
  3. 服務器接收請求,根據 url 來加載相應組件,然後生成 html 發送給客戶端
  4. 客戶端激活, Vue 在瀏覽器端接管由服務端發送的靜態 HTML,使其變爲由 Vue 管理的動態 DOM,爲確保混合成功,客戶端與服務器端需要共享同一套數據。在服務端,可以在渲染之前獲取數據,填充到 stroe 裏,這樣,在客戶端掛載到 DOM 之前,可以直接從 store 裏取數據。首屏的動態數據通過 window.INITIAL_STATE 發送到客戶端

數據雙向綁定原理

實現數據綁定的常見做法:

  • Object.defineProperty:劫持各個屬性的settergetter
  • 髒值檢測:通過特定事件進行輪循
  • 發佈/訂閱模式:通過消息發佈並將消息進行訂閱

vue採用的是數據劫持結合發佈者-訂閱者模式的方式,通過Object.defineProperty()來實現對屬性的劫持,並在數據變動時發佈消息給訂閱者,使其觸發相應的監聽回調。

具體步驟:

1、 實現Observer

將需要observe的數據對象進行遞歸遍歷,包括子屬性對象的屬性,都加上settergetter。實現一個消息訂閱器,維護一個數組,用來收集訂閱者,數據變動觸發notify,再調用訂閱者的update方法

2、 實現Compile

compile解析模板指令,將模板中的變量替換成數據,然後初始化渲染頁面視圖,並將每個指令對應的節點綁定更新函數,添加監聽數據的訂閱者,一旦數據有變動,收到通知,更新視圖

3、 實現Watcher

Watcher訂閱者是Observer和Compile之間通信的橋樑

主要做的事情是:

  • 在自身實例化時往屬性訂閱器(dep)裏面添加自己
  • 自身必須有一個update()方法
  • 待屬性變動dep.notice()通知時,能調用自身的update()方法,並觸發Compile中綁定的回調,則功成身退。

4、 實現MVVM

MVVM作爲數據綁定的入口,整合Observer、Compile和Watcher三者,通過Observer來監聽自己的model數據變化,通過Compile來解析編譯模板指令,最終利用Watcher搭起Observer和Compile之間的通信橋樑,達到數據變化 -> 視圖更新;視圖交互變化(input) -> 數據model變更的雙向綁定效果

參考:剖析Vue原理&實現雙向綁定MVVM

對Vue.js的template編譯的理解

template會被編譯成AST語法樹,AST會經過generate得到render函數,render的返回值是VNode,VNode是Vue的虛擬DOM節點

  • parse 過程,將 template 利用正則轉化成 AST 抽象語法樹。
  • optimize 過程,標記靜態節點,後 diff 過程跳過靜態節點,提升性能。
  • generate 過程,生成 render 字符串

司徒大佬有一篇很好的文章:前端模板的原理與實現

vue 爲什麼採用Virtual DOM

一方面是出於性能方面的考量:

  • 創建真實DOM的代價高:真實的 DOM 節點 node 實現的屬性很多,而 vnode 僅僅實現一些必要的屬性,相比起來,創建一個 vnode 的成本比較低。
  • 觸發多次瀏覽器重繪及迴流:使用 vnode ,相當於加了一個緩衝,讓一次數據變動所帶來的所有 node 變化,先在 vnode 中進行修改,然後 diff 之後對所有產生差異的節點集中一次對 DOM tree 進行修改,以減少瀏覽器的重繪及迴流

但是性能受場景的影響是非常大的,不同的場景可能造成不同實現方案之間成倍的性能差距,所以依賴細粒度綁定及 Virtual DOM哪個的性能更好不是一個容易下定論的問題。更重要的原因是爲了解耦HTML依賴,這帶來兩個非常重要的好處是:

  • 不再依賴 HTML 解析器進行模版解析,可以進行更多的 AOT 工作提高運行時效率:通過模版 AOT 編譯,Vue 的運行時體積可以進一步壓縮,運行時效率可以進一步提升;
  • 可以渲染到 DOM 以外的平臺,實現 SSR、同構渲染這些高級特性,Weex 等框架應用的就是這一特性。

綜上,Virtual DOM 在性能上的收益並不是最主要的,更重要的是它使得 Vue 具備了現代框架應有的高級特性。

diff算法

這部分比較複雜,不好懂,推薦一篇不錯的文章: 解析vue2.0的diff算法

vue 和 react 區別

相同點:

  • 都支持SSR
  • 都有Virtual DOM
  • 組件化開發
  • 數據驅動
  • ...

不同點:

  • vue推薦的是使用 webpack + vue-loader 的單文件組件格式,React 推薦的做法是 JSX + inline style
  • vue 的Virtual DOM是追蹤每個組件的依賴關係,不會渲染整個組件樹,react 每當應該狀態被改變時,全部子組件都會 re-render
  • ...


作者:Alvin_Liu
鏈接:https://juejin.im/post/5ab2ff496fb9a028c06ab78f
來源:掘金
著作權歸作者所有。商業轉載請聯繫作者獲得授權,非商業轉載請註明出處。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章