本文只是對Vue.js 官方SSR文檔和對 官方hackernews demo的我的學習總結,說得不夠完整的請見諒
本文主要對如下幾方面內容對Vue.js SSR的內容進行分析總結javascript
若是用一句話歸納Vue.js SSR的運做過程,那就是在服務端將Vue.js實例轉換成html字符串傳輸到客戶端,而後進行客戶端激活,使網頁內容能在Vue實例的控制之下html
這一句話包含兩步內容vue
先來看第一步java
一個最簡單的Vue.js單頁應用是這樣的:webpack
new Vue({ render: h => h('div', '123') }).$mount('#app')
這裏也包含兩步git
在服務端當中咱們不進行上面第二步操做,取而代之的是將這個實例直接渲染成字符串,作這個工做的就是咱們的vue-server-renderer
github
const renderer = require('vue-server-renderer').createRenderer() const Vue = require('vue') renderer.renderToString(new Vue({ render: h => h('div', 123) })).then(html => { console.log(html) }).catch(err => { console.error(err) }) // 輸出<div data-server-rendered="true">123</div>
到如今一個最簡單的vue ssr應用在服務端的工做已經完成了,下面咱們轉向下一步客戶端激活web
客戶端激活跟咱們單頁應用所作的工做相比,最大的不一樣點就是它並不會構建DOM元素,只會對現有的DOM元素進行激活,使它們能被Vue實例進行控制,而判斷激活的關鍵就是上面的data-server-rendered
屬性vue-router
至此,最簡單的一個SSR應用已經構建完成了,下面是對這個應用的功能進行進一步的補充vuex
數據預取包含着兩個方面,客戶端的數據預取和服務端的數據預取
咱們渲染一個內容完整頁面的時候每每須要向服務器請求數據,因此如今服務端的邏輯變成等待數據獲取完畢,而後將頁面轉換成html字符串
其中數據獲取有如下幾個問題:
問題1:
咱們的數據用來渲染頁面,那麼咱們就須要組成當前頁面的全部組件各自所須要的數據
問題2:
每一個須要進行服務端數據預取的組件定義一個asyncData
方法,此方法用於數據預取
問題3:
咱們須要先獲得當前頁面全部須要渲染的組件,而後再進行數據預取
問題4:
因爲還須要進行數據同步,因此很難將數據保存在組件的私有data上面,放在vuex上面是個廣泛的選擇
問題5:
服務端在返回html字符串的時候,store數據將被序列化之後以window.__INITIAL_STATE__=/* store state */
的形式插入到腳本當中被客戶端獲取,客戶端的store使用store.replaceState
方法同步state
簡單複述一下上面的流程就是:
在渲染當前頁面的全部組件加載完畢之後,執行這些組件的asyncData
方法,這些方法將獲取到的數據將由vuex
託管,獲取數據完畢之後便可將應用渲染成html字符串,vuex store的state將會被序列化之後一併傳輸到客戶端,被客戶端進行同步
下面是實現的一些細節:
因爲源碼太長因此沒貼出來,具體能夠到官網瀏覽
服務端數據預取的關鍵點算是總結的差很少了,下面簡單說一下客戶端的數據預取
客戶端的數據預取方法可分爲兩種:
兩種方法區別在於讓用戶在何時產生等待的感受,第一種是在頁面切換時,而第二種是在頁面切換完畢等待內容的出現時
第一種方法的實現使用了vue-router實例的beforeResolve
方法,這個方法執行在異步組件加載完畢後,導航被確認以前,當完成數據預取之後router纔會進行DOM更新等步驟
第二種方法的實現跟咱們通常進行數據獲取一致,在beforeMount鉤子當中執行
以官方的hackernews demo爲例,webpack有兩個入口entry-client
和entry-server
分別負責構建客戶端和服務端的文件
服務端方面webpack會輸出一個名叫vue-ssr-server-bundle
的json文件,此文件由官方提供的VueSSRServerPlugin
插件所構建而成,是服務端的構建清單,傳入createBundleRenderer
生成服務端渲染所須要的renderer
客戶端方面webpack輸出的是由代碼分割而成的chunk和公用bundle,與通常單頁應用的構建類似,不一樣的是會生成一個vue-ssr-client-manifest
,此文件是客戶端方面的構建清單,包含全部chunk的信息,將其傳入上面的renderer當中能自動將chunk嵌入到html當中,固然用戶也可以取消,自行選擇手動嵌入的內容